Skip to content

Output Channels and Routing

After a review finishes, AICodeReviewer dispatches the result to one or more output channels — PR line comments, IM bots, managed issues — based on routing rules. The outputs namespace defines the channels, the routes, the template engine, and the zero-problem policy that decides whether a clean review should notify anyone.

outputs:
template_engine: handlebars
no_problems: { action: suppress }
channels:
- name: gitea-pr-review
kind: gitea_pr_review
trigger: gitea
routes:
default:
line_comments: [gitea-pr-review]
summary: [gitea-pr-review]
Value Description
handlebars (default) Handlebars templates (*.hbs). Built-ins live in templates/builtin/*.hbs.
eta Reserved — accepted by the schema, but only Handlebars is implemented; setting it has no effect.

Override templates per workspace by placing files under workspaces/<workspace_id>/templates/. Candidate file names are checked in order: <channel_name>.<kind>.md.hbs<channel_name>.<kind>.hbs<channel_kind>.<kind>.md.hbs<channel_kind>.<kind>.hbs<kind>.md.hbs<kind>.hbs.

outputs.no_problems — zero-problem policy

Section titled “outputs.no_problems — zero-problem policy”

Decides whether a successful review with no actionable problems should notify each channel.

action Behavior
suppress Do not notify when there are no problems.
publish Always notify, even with zero problems.
publish_if_summary Notify only if a non-empty summary was produced.

When nothing is configured, the default depends on the channel kind: managed problem-issue channels (*_problem_issue) default to publish — publishing is what drives stale issues to close; IM bots default to publish_if_summary; everything else defaults to suppress.

The policy is set at three levels, each more specific:

  1. outputs.no_problems (global default for all channels)
  2. per-channel no_problems inside outputs.channels[]
  3. per-workspace + per-channel via workspaces.instances.<id>.outputs.channel_overrides.<channel>.no_problems
outputs:
no_problems: { action: suppress }
channels:
- name: feishu-code-review
kind: feishu_bot
no_problems: { action: suppress }
workspaces:
instances:
critical-service:
outputs:
channel_overrides:
feishu-code-review:
no_problems: { action: publish } # this repo wants an audit trail

If all selected summary channels suppress a zero-problem result, the run is recorded as skipped with skipReason="no_problems_suppressed".

Every channel has a name (referenced by routes and workspace output lists) and a kind. The common fields below apply to most kinds; kind-specific fields are listed under each kind.

Field Type Description
name string Unique channel id.
kind string Channel kind (see list below). gitea_finding_issue is removed — use gitea_problem_issue.
trigger string Trigger name this channel binds to (for VCS-backed kinds).
mention_author bool @-mention the commit author in the message. Defaults to true for VCS PR/issue kinds and false for IM bots.
mention_fallback enum all (mention everyone) or skip (no mention if author not found).
no_problems object Per-channel zero-problem policy (see above).
commit_url_template string Override commit link for push/commit targets.
revision_url_template string Override revision link (P4/SVN).
change_url_template string Override change link.
marker_prefix string Title prefix for managed issues (e.g. [AICR]).
marker_label string Hidden label identifying managed issues (e.g. aicr-managed).
labels string[] Labels to attach.
label_ids int[] Numeric label ids (some VCS APIs).
issue_mode enum per_problem, consolidated (default), or per_commit.
resolved_action enum none, close, mark_resolved, or delete. Action when a problem is fixed.
assign_committer bool Add the commit author as assignee (default true).
owners_file string Path to OWNERS file (default OWNERS).
add_owners_as_assignees bool Add matched OWNERS as assignees.
severity_label_prefix string Auto-created label prefix (e.g. aicr:problem:).
severity_label_colors map Custom label colors (hex without #).
review_mode enum auto (default), review, or comment.
review_event enum COMMENT (default) or REQUEST_CHANGES.
review_update_strategy enum always_new or update_existing (default).
notify_feishu object Optional Feishu notify-on-issue-creation (webhook_url_env, secret_env).
Kind Description
gitea_pr_review Inline line comments on Gitea/Forgejo pull requests.
github_pr_review Inline line comments on GitHub pull requests.
gitlab_mr_review Inline line comments on GitLab merge requests.
gitea_problem_issue Managed Gitea issues created/closed per problem fingerprint.
github_problem_issue Managed GitHub issues per problem fingerprint (no delete — GitHub does not support it).
gitea_issue Post the aggregated review as a comment on an existing Gitea issue.
github_issue Post the aggregated review as a comment on an existing GitHub issue.
feishu_bot Push aggregated problems to a Feishu (飞书) group via custom bot.
wecom_bot Push aggregated problems to a WeCom (企业微信) group via webhook.

For *_pr_review / *_mr_review kinds:

Value Behavior
auto (default) Try the PR review API first; fall back to issue comment on 403/422.
review Always use the PR review API, no fallback.
comment Always post a plain issue comment, never the review API.

The companion review_event field controls the event type used with the review API: COMMENT (default) or REQUEST_CHANGES.

review_update_strategy controls how the PR summary behaves across pushes:

Value Behavior
always_new Create a new review/comment on every push (original behavior).
update_existing (default) Find and update the previous AICR summary comment on the PR. Open issues are kept; resolved issues are marked with ✅; new issues are tagged with the introducing commit.

AICR identifies its own managed comments via stable managed comment markers derived from marker_prefix/marker_label, so only AICR-owned summary comments are updated and other comments are left untouched.

outputs.routes — send results to the right channels

Section titled “outputs.routes — send results to the right channels”

Routes map review outputs (line_comments and summary) to channel lists. A default route applies to every event; rules[] override for specific triggers or target kinds.

outputs:
routes:
default:
line_comments: [gitea-pr-review]
summary: [gitea-pr-review]
rules:
- match:
trigger: p4-main
target_kind: commit
summary: [feishu-code-review]
- match:
trigger: github
target_kind: push
summary: [feishu-code-review, github-problem-issues]
Field Type Description
default.line_comments string[] Channels for inline line comments.
default.summary string[] Channels for the aggregated summary.
rules[].match.trigger string Match events from this trigger name.
rules[].match.target_kind string Match a target kind (e.g. commit, push, pull_request). pr is normalized to pull_request.
rules[].line_comments string[] Override line-comment channels for matched events.
rules[].summary string[] Override summary channels for matched events.

Per-workspace output lists (workspaces.instances.<id>.outputs.line_comments and .summary) take precedence over the global routes for that workspace.

AICodeReviewer can skip reviews based on labels and auto-tag PRs/MRs/issues. This lives under review (not outputs) but is closely related to output dispatch.

review:
labels:
ignore: ["aicr:ignore", "aicr-ignore"] # skip review if any label matches
auto_tag: "aicr" # tag added when AICR starts
reviewed_tag: "aicr:reviewed" # tag added when review completes
Field Behavior
ignore Checked at the webhook layer. If a PR/MR/issue carries any listed label, AICR returns immediately without scheduling a review.
auto_tag Fixed tag applied by output dispatchers (gitea_pr_review, github_pr_review, gitlab_mr_review, gitea_issue, gitea_problem_issue) when publishing. Created automatically if missing.
reviewed_tag Tag applied when a review completes.

All fields support the global → workspace-level override layering.

gitea_problem_issue and github_problem_issue reconcile stale managed issues by listing only the most recent open issues. The cap lives under review.problem_issue and can be tightened per workspace.

review:
problem_issue:
max_recent_issues: 20 # default; valid range is 1..100
workspaces:
instances:
latency-sensitive-service:
review:
problem_issue:
max_recent_issues: 10

If a repository has more open managed issues than the limit, fingerprints outside the recent window are not deduplicated or closed in that run. Later runs — or a temporarily raised cap — handle large cleanup runs.

If one configured output channel cannot publish, AICR logs the channel failure and continues trying the remaining routed channels. A run where every dispatch attempt fails is reported as skipped with skipReason: output_dispatch_failed (instead of review_orchestration_failed), so the review result and failure cause stay visible without poisoning the trigger queue.

Built-in templates render target.markdownLink / target.displayText instead of assuming every review is a PR. Gitea, Forgejo, GitHub, and GitLab commit links are derived from trigger base_url, repo, and revision. P4/SVN/internal systems provide explicit URL templates via the trigger’s change_url_template or revision_url_template (variables are URL-encoded before substitution):

triggers:
- name: p4-main
kind: p4
change_url_template: "https://swarm.example.com/changes/{{revision}}"
- name: svn-main
kind: svn
revision_url_template: "https://svn.example.com/viewvc/project?view=revision&revision={{revision}}"
  • The full per-channel field contract, including the MCP tool contract that agents use to fetch more context, is in Output channels.
  • For trigger-side URL templates and file filters, see VCS providers.