This guide covers how to configure Watchflow rules. Rules are description + event_types + parameters; the engine matches parameter keys to built-in conditions. No custom code—just YAML in .watchflow/rules.yaml on the default branch.
Pro tip: Test rule ideas at watchflow.dev. Use “Evaluate” for feasibility and suggested YAML, or run repo analysis to get a full suggested config. When you land from the app install flow (?installation_id=...&repo=owner/repo), no PAT is required.
Each rule has:
| Field | Required | Description |
|---|---|---|
description |
Yes | Short human-readable description (used in check runs and comments). |
enabled |
No | Default true. Set false to disable without deleting. |
severity |
No | low | medium | high | critical. Drives presentation, not logic. |
event_types |
Yes | Events this rule runs on: pull_request, push, deployment, etc. |
parameters |
Yes | Key-value map. Keys determine which condition runs (e.g. require_linked_issue, max_lines). |
The loader reads .watchflow/rules.yaml from the repo default branch and builds Rule objects with condition instances from the condition registry. Parameter names must match what the conditions expect; see below.
Linked issue
parameters:
require_linked_issue: true
PR must reference an issue (e.g. “Fixes #123”) in title or body.
Title pattern
parameters:
title_pattern: "^feat|^fix|^docs|^style|^refactor|^test|^chore|^perf|^ci|^build|^revert"
PR title must match the regex (e.g. conventional commits).
Description length
parameters:
min_description_length: 50
PR body length must be ≥ N characters.
Required labels
parameters:
required_labels: ["Type/Bug", "Type/Feature", "Status/Review"]
PR must have all of these labels.
Min approvals
parameters:
min_approvals: 2
At least N approvals required.
Max PR size (lines)
parameters:
max_lines: 500
Total additions + deletions must be ≤ N. The loader also accepts max_changed_lines as an alias.
CODEOWNERS: require owners as reviewers
parameters:
require_code_owner_reviewers: true
For every file changed, the corresponding CODEOWNERS entries must be in the requested reviewers (users or teams). If CODEOWNERS is missing, the condition skips (no violation).
CODEOWNERS: path must have owner
parameters:
require_path_has_code_owner: true
Every changed path must have at least one owner in CODEOWNERS. If CODEOWNERS is missing, the condition skips.
Critical paths / code owners
parameters:
critical_owners: [] # or list of path patterns if supported
Changes to critical paths require code-owner review. (See registry for exact semantics.)
Protected branches
parameters:
protected_branches: ["main", "master"]
Blocks targeting these branches (e.g. merge without going through PR flow as configured).
No force push
parameters:
no_force_push: true
Reject force pushes. Typically used with event_types: ["push"].
Max file size
parameters:
max_file_size_mb: 1
No single file in the PR may exceed N MB.
File pattern
parameters:
pattern: "tests/.*\\.py$|test_.*\\.py$"
condition_type: "files_match_pattern"
Changed files must (or must not) match the pattern; exact behavior depends on condition.
Allowed hours, days, weekend — See condition registry and examples in repo for allowed_hours, timezone, days, and deployment-related parameters.
Restricted diff patterns
parameters:
diff_restricted_patterns: ["console\\.log", "TODO:", "debugger"]
Flag added lines in the PR diff that match any of the listed regex patterns.
Security pattern detection
parameters:
security_patterns: ["api_key", "secret", "password", "token"]
Detect hardcoded secrets or sensitive data in PR diffs. Violations are raised with critical severity.
Test coverage enforcement
parameters:
require_tests: true
test_file_pattern: "^tests/.*" # optional, defaults to common test paths
Source file changes must include corresponding test file changes. Ignored file types: .md, .txt, .yaml, .json.
Unresolved review comments
parameters:
block_on_unresolved_comments: true
Block merge when unresolved (non-outdated) review comment threads exist on the PR.
Comment response time SLA
parameters:
max_comment_response_time_hours: 24
Flag unresolved review threads that have exceeded the specified hour-based SLA.
Self-approval prevention
parameters:
block_self_approval: true
PR authors cannot approve their own pull requests. Violations are raised with critical severity.
Cross-team approval
parameters:
required_team_approvals: ["backend", "security"]
Require approvals from members of specified GitHub teams before merge.
Signed commits
parameters:
require_signed_commits: true
All commits in the PR must be cryptographically signed (GPG, SSH, or S/MIME). Required for SOC2/FedRAMP compliance.
Changelog required
parameters:
require_changelog_update: true
PRs that modify source code must include a corresponding CHANGELOG.md or .changeset/ update. Docs, tests, and .github/ paths are excluded.
Description-diff alignment
parameters:
require_description_diff_alignment: true
Uses the configured AI provider to check whether the PR description semantically reflects the actual code changes. Flags mismatches like “description says fix login but diff only touches billing code.” Adds ~1-3s latency per evaluation. If the LLM is unavailable (provider not configured, rate limit), the condition gracefully skips without blocking the PR.
Linked issue + PR size + CODEOWNERS reviewers
rules:
- description: "PRs must reference a linked issue (e.g. Fixes #123)"
enabled: true
severity: high
event_types: ["pull_request"]
parameters:
require_linked_issue: true
- description: "PR total lines changed must not exceed 500"
enabled: true
severity: medium
event_types: ["pull_request"]
parameters:
max_lines: 500
- description: "When a PR modifies paths with CODEOWNERS, those owners must be added as reviewers"
enabled: true
severity: high
event_types: ["pull_request"]
parameters:
require_code_owner_reviewers: true
Title pattern + description length
rules:
- description: "PR titles must follow conventional commit format; descriptions must be at least 50 chars"
enabled: true
severity: medium
event_types: ["pull_request"]
parameters:
title_pattern: "^feat|^fix|^docs|^style|^refactor|^test|^chore"
min_description_length: 50
No force push to main
rules:
- description: "No direct pushes to main - all changes must go through PRs"
enabled: true
severity: critical
event_types: ["push"]
parameters:
no_force_push: true
Severity affects how violations are presented in check runs and comments; it does not change the condition logic.
no_force_push for branch protection).@watchflow acknowledge and similar commands.Rules are loaded from .watchflow/rules.yaml on the repo default branch (e.g. main) via the GitHub API using the installation token. So:
.watchflow/rules.yaml take effect after merge to the default branch.require_linked_issue, require_code_owner_reviewers), then add more..watchflow/rules.yaml in the repo and review rule changes in PRs.@watchflow acknowledge "reason" for legitimate one-off exceptions; don’t use it to bypass policy routinely.For the full list of conditions and parameter names, see Features and the source: src/rules/conditions/ and src/rules/registry.py.