Saltar al contenido

Docs / Referencia de .maintainer.yml

.maintainer.yml reference

Complete field reference for the .maintainer.yml policy file.

.maintainer.yml reference

Drop a .maintainer.yml at your repository root to configure the maintainer bot. The file is YAML; all fields are optional and default-safe — an empty file with only version: 1 is valid.

Schema autocomplete. Add # yaml-language-server: $schema=https://developerz.ai/schemas/maintainer.v1.json as the first line of the file to get IDE validation and autocomplete.

Minimal example

# yaml-language-server: $schema=https://developerz.ai/schemas/maintainer.v1.json
version: 1

Full example

# yaml-language-server: $schema=https://developerz.ai/schemas/maintainer.v1.json
version: 1

tone:
  voice: friendly
  language: en

triage:
  ask_for_repro: true
  required_fields: [steps, expected, actual, version]
  dedupe:
    enabled: true
    similarity_threshold: 0.85
  qualify_into: [bug, feature, dupe, question]

handoff:
  mode: webhook
  webhook_ref: my-claude-code-hook
  ask_reporter_first: true

pr:
  wait_for_other_bots: [coderabbit, copilot]
  required_checks: [ci]
  large_threshold_lines: 500
  auto_merge: true
  human_merge:
    branches: [main]
    paths: [db/migrations/**]

release:
  manager: release-please
  channels: [github-release]

escalate:
  always: [security, license, cla]
  ask_before_acting: [breaking, major, first-time-contributor, large]

digest:
  cadence: weekly
  day: monday
  time: "09:00"
  timezone: maintainer

limits:
  max_steps_per_session: 50
  max_comments_per_issue_per_day: 10

kb:
  repo_notes:
    - note: "Auth lives in packages/auth; ignore the legacy auth-old/ tree."
      by: "@maintainer"
  pages:
    - title: Architecture
      purpose: How the worker dispatches jobs.
  memory:
    stale_after_days: 90
    delete_unused_after_days: 40

review:
  profile: chill
  learnings: true
  anti_noise:
    severity_floor: minor
    max_comments: 30
  path_filters: ["!**/*.lock", "!dist/**"]

Root fields

Field Type Required Description
version 1 yes Schema version. Must be 1.
schema URL string no JSON schema URL for editor tooling.
format_command string (shell command) no Formatter the bot runs before git add on the BYOVM (e.g. biome check --write ., gofmt -w .). Non-zero exit fails the commit rather than failing CI later.

tone

Controls the bot's voice and language in all comments.

Field Type Default Description
voice friendly | formal | terse friendly Persona used in all bot comments.
greeting_template_ref string (ref name) default Name of a greeting template configured in the dashboard.
language BCP-47 string en BCP-47 language tag for bot-generated copy (e.g. en, de, pt-BR).

triage

Governs how new issues are triaged: reproduction requests, deduplication, and label outcomes.

Field Type Default Description
ask_for_repro boolean true Bot asks reporters for a reproduction before qualifying the issue.
required_fields steps | expected | actual | version | environment | logs[] [steps, expected, actual, version] Checklist items the bot requests when ask_for_repro is enabled.
dedupe.enabled boolean true Vector-similarity deduplication against open issues.
dedupe.similarity_threshold number 0–1 0.85 Cosine similarity cutoff (0–1). Issues scoring above this are flagged as duplicates.
qualify_into bug | feature | dupe | question | docs | chore[] [bug, feature, dupe, question] Allowed outcome labels after triage.

handoff

After qualification, the bot can hand off the issue to a coding agent. mode = webhook fires a signed POST to the configured webhook; mode = label applies a GitHub label your CI or coding agent can pick up; mode = none disables handoff.

When mode = webhook, webhook_ref is required. The webhook must be registered in the dashboard.

Field Type Default Description
mode webhook | label | none none How qualified issues are handed off to a coding agent.
label string GitHub label applied when mode = label.
webhook_ref string (ref name) Dashboard webhook name used when mode = webhook.
ask_reporter_first boolean true Bot asks the reporter for consent before handing off.

pr

Pull request review policy.

auto_merge is on by default. The bot merges once the machine gates pass — CI green, review verdict, and the repo's branch protections — never blindly. To keep a human in the loop, set auto_merge: false or list the sensitive branches/paths under human_merge. (Free-OSS-tier repos stay opt-in regardless.)

Field Type Default Description
wait_for_other_bots coderabbit | copilot | dependabot | renovate[] [coderabbit, copilot, dependabot] Bots the maintainer bot waits for before acting on a PR.
required_checks string[] [] CI check names that must pass before the bot considers merging.
large_threshold_lines integer > 0 500 PRs exceeding this line delta trigger an ask_before_acting escalation.
auto_merge boolean true On by default. The bot merges once the machine gates pass — CI green, review verdict, and branch protections satisfied. Set false (or use human_merge) to hand the merge back to a human.
human_merge.branches string[] (globs) [] Target-branch globs held for a human even when auto_merge is on (e.g. main, release/*).
human_merge.paths string[] (globs) [] Changed-path globs held for a human even when auto_merge is on (e.g. db/migrations/**, **/*.tf).

release

Release automation. The bot can cut releases after a PR merges based on conventional commit history.

Field Type Default Description
manager release-please | none release-please Release automation driver.
channels github-release | npm | crates | pypi | rubygems[] [github-release] Registries the bot publishes to when cutting a release.

escalate

Escalation rules. The bot always escalates security, license, and cla issues regardless of configuration — these cannot be disabled.

Field Type Default Description
always string[] [] Categories that immediately email the maintainer (in addition to the hardcoded security, license, cla set).
ask_before_acting string[] [] Conditions that pause the bot and request explicit approval before continuing.

Built-in always categories (non-configurable): security, license, cla.

Built-in ask_before_acting categories: breaking, major, first-time-contributor, large.


digest

Weekly (or daily/monthly) email digest sent to the maintainer.

Field Type Default Description
cadence daily | weekly | monthly weekly How often the digest email is sent.
day monday | tuesday | ... | sunday monday Day of the week for weekly digests.
time HH:MM 24 h 09:00 Delivery time in HH:MM 24 h format.
timezone maintainer or IANA string maintainer maintainer uses the timezone from your GitHub profile. Otherwise any IANA zone (e.g. Europe/Berlin).

limits

Hard caps that prevent runaway agent behaviour.

Field Type Default Description
max_steps_per_session integer > 0 50 Hard cap on LLM tool-call steps per agent session.
max_comments_per_issue_per_day integer > 0 10 Throttle on bot comments to prevent spam.

coding

Knobs for the on-VM coding agent (BYOVM). Concurrency is a policy value, not a flag: it caps how many isolated git worktree checkouts run in parallel for the repo.

Field Type Default Description
max_concurrent_worktrees integer 1–64 1 Max parallel git worktree checkouts the on-VM coding agent runs for this repo (the WorktreePool semaphore capacity). Default 1 (single concurrency).

ci

Fences for the self-hosted CI runners the fleet boxes serve. The per-workflow opt-in is the label itself (runs-on: developerz-*); these two repo-wide booleans sit on top of it. Both are defaulted, so a repo that commits a policy but omits ci: still gets the safe fences.

Field Type Default Description
enabled boolean true Kill switch for the self-hosted CI lane. The developerz-* runner labels are the opt-in per workflow; set false to stop placing CI jobs on fleet boxes without editing every workflow file.
public_repos boolean false Non-negotiable public-repo fence. Off by default — a public repo lets any contributor open a PR whose workflow runs on your hardware, so the ci-assigner refuses to place a public-repo job unless a maintainer flips this on.

mcp_servers

Array of external MCP servers the agent may call. Each entry:

Field Type Default Description
name ref name string Unique identifier for this server (used in audit logs).
url URL Base URL of the MCP endpoint.
transport sse | http-streamable | stdio Transport protocol.
token_ref string (ref name) Dashboard secret name injected as Authorization: Bearer.
allowed_tools string[] ["*"] ["*"] allows all tools. Otherwise an explicit allowlist.
timeout_ms integer 1–60 000 5000 Per-request timeout in milliseconds (max 60 000).

Ref names (token_ref) resolve to secrets registered in the dashboard. The value is never stored in the policy file.

Example

mcp_servers:
  - name: linear
    url: https://mcp.linear.app/sse
    transport: sse
    token_ref: linear-api-key
    allowed_tools: [create_issue, search_issues]
    timeout_ms: 10000

kb

Repo-steered knowledge — a committed, reviewable way to correct or seed the agent's understanding of your repo. The bot reads it during triage alongside what it has learned on its own, so a short note here grounds answers without any code change.

kb.repo_notes

Short, attributed facts. Combined note length is capped at 10 000 characters.

Field Type Default Description
note string 1–1 000 The fact itself (1–1 000 chars).
by string 1–120 Who asserted it — a GitHub login, team, or name. Optional.

kb.pages

An explicit table-of-contents that overrides the agent's auto-clustering. Up to 30 pages; titles must be unique and any parent must name another page.

Field Type Default Description
title string 1–120 (unique) Page title (1–120 chars, unique across pages).
purpose string 1–500 One-line description of what the page covers (1–500 chars).
parent string (existing title) Title of the parent page for a shallow tree. Must name an existing page.
notes string ≤2 000 Optional longer prose for the page (≤2 000 chars).

kb.memory

Retention and consolidation settings for the bot's accumulated memories (learnings from past reviews, issues, and discussions). Distinct from repo_notes and pages (which are explicit, human-authored steering). Memory entries that grow stale or unused are pruned or merged automatically by the nightly gardener; these knobs tune that cleanup.

Field Type Default Description
stale_after_days integer ≥7 90 A memory entry untouched this long (days) is eligible for consolidation into a KB page.
delete_unused_after_days integer ≥7 false 40
consolidate boolean true Merge/summarize stale-but-still-referenced memory entries instead of leaving them to rot.

Consolidation. When consolidate: true, the gardener summarizes stale-but-still- referenced memories into KB pages via the account's BYOK model. When false, they are left as-is (or deleted if unused). Deletion. Set delete_unused_after_days to false to keep all memories forever; set a numeric value ≥7 to delete memories that have never been recalled (or recalled before the deletion cutoff).

Example

kb:
  repo_notes:
    - note: "Auth lives in packages/auth; ignore the legacy auth-old/ tree."
      by: "@maintainer"
    - note: "We never accept PRs that touch the vendored/ directory."
  pages:
    - title: Architecture
      purpose: How the worker dispatches jobs.
    - title: Dispatch
      purpose: Two-phase pull queue + per-entity lock.
      parent: Architecture
  memory:
    stale_after_days: 90
    delete_unused_after_days: 40
    consolidate: true

review

Native AI code review — a hosted, CodeRabbit-compatible reviewer running on your BYOK model, included in the seat. The native review: block is a superset of .coderabbit.yaml (adds anti-noise floor/cap and KB learning write-back); when the bot reads a .coderabbit.yaml it honors most fields but defers reviews.tools and reviews.finishing_touches (surfaced as warnings).

Precedence. If a repo has both a .coderabbit.yaml and a review: block, the review: block wins (.maintainer.yml > .coderabbit.yaml). The block is optional — omit it and the bot reads your existing .coderabbit.yaml (if any) or falls back to the built-in review defaults. Migrating off CodeRabbit is a no-op: keep the file, uninstall their app.

Bot etiquette. The reviewer always defers when another review bot (e.g. CodeRabbit, Copilot, Dependabot) is active on the repo — no bot-on-bot loops, no override. To hand review to the native reviewer, uninstall the other bot.

Field Type Default Description
enabled boolean true Master switch for the native reviewer.
force boolean false Review even when another review bot (CodeRabbit) is active on the repo. Off by default so two bots never double-review the same PR; turn on while migrating off CodeRabbit.
profile chill | assertive chill chill posts fewer, higher-signal comments (raises the default severity floor); assertive surfaces more, including minor issues.
language BCP-47 string en-US BCP-47 language tag for review copy (e.g. en-US, de).
tone_instructions string ≤4 000 "" Free-text steering for the reviewer’s voice and emphasis.
request_changes boolean false Emit a request_changes verdict (not just a comment) when a blocking finding exists.
high_level_summary boolean true Post a single top-level walkthrough/summary comment on the PR.
learnings boolean true Write review learnings back to the repo knowledge base (kb) so later reviews cite them — the CodeRabbit-style moat feature.
chat_auto_reply boolean true Reply to review comment threads automatically.
labels.suggest boolean false Suggest labels for the PR.
labels.auto_apply boolean false Apply suggested labels automatically.
reviewers.suggest boolean false Suggest human reviewers for the PR.
reviewers.auto_assign boolean false Assign suggested reviewers automatically.
auto_review.enabled boolean true Review PRs automatically on open/synchronize.
auto_review.incremental boolean true On a re-push, review only the new commits rather than the whole diff again.
auto_review.drafts boolean false Review draft PRs too.
auto_review.base_branches string[] [main] Only auto-review PRs targeting one of these base branches.
auto_review.ignore_title_keywords string[] [] Skip PRs whose title contains any of these (e.g. WIP, DO NOT MERGE).
anti_noise.severity_floor critical | major | minor | nit minor Drop findings below this severity. Blocking findings always bypass it. Overrides the profile-derived floor.
anti_noise.max_comments integer 1–200 30 Cap on non-blocking inline comments per review. Blocking findings are always kept.
anti_noise.dedupe boolean true Collapse repeated findings against prior reviews on re-push.
path_filters string[] (globs) [] Glob filters applied before chunking; a leading ! excludes a path.
path_instructions { path, instructions }[] [] Per-glob free-text guidance the reviewer applies to matching files.

Anti-noise. Quiet by default (their #1 complaint): findings below anti_noise.severity_floor are dropped, volume is capped at max_comments, and repeats are deduped on re-push. Blocking findings (principle/gate violations) always bypass both the floor and the cap.

Example

review:
  profile: chill
  request_changes: true
  learnings: true # write review learnings back to kb
  anti_noise:
    severity_floor: minor
    max_comments: 30
  auto_review:
    base_branches: [main, release/*]
    ignore_title_keywords: [WIP, "DO NOT MERGE"]
  path_filters: ["!**/*.lock", "!dist/**"]
  path_instructions:
    - path: "packages/**/*.ts"
      instructions: "Enforce the repo principles in docs/idea/principles.md."

This page is generated from packages/policy/src/schema.ts. Run bun run scripts/policy-doc.ts to regenerate.