<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gaurav Sharma</title>
    <description>The latest articles on DEV Community by Gaurav Sharma (@gauravsharmagg).</description>
    <link>https://dev.to/gauravsharmagg</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3955976%2Fda60f52d-99d1-4ecf-92b6-8f77552fe59e.png</url>
      <title>DEV Community: Gaurav Sharma</title>
      <link>https://dev.to/gauravsharmagg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gauravsharmagg"/>
    <language>en</language>
    <item>
      <title>How to run AI security code review on GitHub pull requests without alert fatigue</title>
      <dc:creator>Gaurav Sharma</dc:creator>
      <pubDate>Sat, 24 Oct 2026 21:44:36 +0000</pubDate>
      <link>https://dev.to/gauravsharmagg/how-to-run-ai-security-code-review-on-github-pull-requests-without-alert-fatigue-26f3</link>
      <guid>https://dev.to/gauravsharmagg/how-to-run-ai-security-code-review-on-github-pull-requests-without-alert-fatigue-26f3</guid>
      <description>&lt;p&gt;&lt;strong&gt;To run AI security code review on GitHub pull requests without drowning in false alarms, run deterministic rules first for hard stops (secrets, removed CI safety guards, and protected paths), then use an evidence-gated security checklist that only raises a pull request's risk lane when the model quotes an exact line from the diff.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mergejudge.si/?utm_source=devto" rel="noopener noreferrer"&gt;MergeJudge&lt;/a&gt; is an AI pull request reviewer with an open-source engine for GitHub. Every pull request is sorted into an &lt;code&gt;auto&lt;/code&gt;, &lt;code&gt;review&lt;/code&gt; or &lt;code&gt;block&lt;/code&gt; lane: deterministic rules set the floor first, and the AI step can only raise a lane. &lt;code&gt;auto&lt;/code&gt; means low risk, not a guarantee; branch protection and required checks still apply, and MergeJudge doesn't merge pull requests itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Deterministic rules run first (no model needed)
&lt;/h2&gt;

&lt;p&gt;Before any model is called, MergeJudge runs deterministic checks on the pull request diff using the &lt;code&gt;.mergejudge.yml&lt;/code&gt; file from the &lt;strong&gt;base branch&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Coarse secret screen (&lt;code&gt;block&lt;/code&gt;):&lt;/strong&gt; Added lines that match common secret formats (such as AWS keys, private key blocks, GitHub tokens, or hard-coded &lt;code&gt;api_key&lt;/code&gt; assignments) put the pull request in &lt;code&gt;block&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Removed safety guards (&lt;code&gt;block&lt;/code&gt;):&lt;/strong&gt; Changes to protected paths that drop &lt;code&gt;--match-head-commit&lt;/code&gt;, &lt;code&gt;persist-credentials: false&lt;/code&gt;, &lt;code&gt;set -e&lt;/code&gt;, or &lt;code&gt;--frozen-lockfile&lt;/code&gt; / &lt;code&gt;npm ci&lt;/code&gt; put the pull request in &lt;code&gt;block&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Protected paths (at least &lt;code&gt;review&lt;/code&gt;):&lt;/strong&gt; Files matching &lt;code&gt;lanes.protected&lt;/code&gt; (by default &lt;code&gt;.github/**&lt;/code&gt;, &lt;code&gt;deploy/**&lt;/code&gt;, &lt;code&gt;**/auth/**&lt;/code&gt;, &lt;code&gt;**/migrations/**&lt;/code&gt;, &lt;code&gt;wrangler.toml&lt;/code&gt;, &lt;code&gt;_headers&lt;/code&gt;, &lt;code&gt;**/_headers&lt;/code&gt;, and &lt;code&gt;**/.env*&lt;/code&gt;) always require human review, even if no AI provider is configured.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Default security rubric (&lt;code&gt;security&lt;/code&gt; pack, on by default):&lt;/strong&gt; When an AI provider is active, every review already scores &lt;code&gt;sec.no-secrets&lt;/code&gt; (&lt;code&gt;block&lt;/code&gt;), &lt;code&gt;sec.no-exfiltration&lt;/code&gt; (&lt;code&gt;block&lt;/code&gt;), &lt;code&gt;sec.no-unsafe-exec&lt;/code&gt; (&lt;code&gt;review&lt;/code&gt;), and &lt;code&gt;sec.input-handling&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because &lt;code&gt;.mergejudge.yml&lt;/code&gt; is read from the base branch tip, a pull request cannot edit &lt;code&gt;.mergejudge.yml&lt;/code&gt; to remove a protected path or turn off a check for itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Turn on optional security review mode
&lt;/h2&gt;

&lt;p&gt;For teams that want a closer security audit on every pull request—especially when reviewing AI-agent pull requests or backend, webhook, and auth changes—MergeJudge includes an optional &lt;strong&gt;Security review mode&lt;/strong&gt;. It is &lt;strong&gt;off by default&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Turn it on in &lt;code&gt;.mergejudge.yml&lt;/code&gt; on your default branch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .mergejudge.yml on the default branch&lt;/span&gt;
&lt;span class="na"&gt;review&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;context&lt;/span&gt;        &lt;span class="c1"&gt;# diff | context | deep&lt;/span&gt;
  &lt;span class="na"&gt;security&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;       &lt;span class="c1"&gt;# default false; only a real boolean true turns it on&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the &lt;a href="https://mergejudge.si/guide/cloud?utm_source=devto" rel="noopener noreferrer"&gt;hosted GitHub App&lt;/a&gt;, you can also flip the &lt;strong&gt;Security review&lt;/strong&gt; switch in the &lt;strong&gt;Set up&lt;/strong&gt; wizard or &lt;strong&gt;Edit settings&lt;/strong&gt; in the panel; it opens a setup pull request on &lt;code&gt;mergejudge/setup-config&lt;/code&gt; for you to merge. On the &lt;a href="https://mergejudge.si/guide/github-action?utm_source=devto" rel="noopener noreferrer"&gt;GitHub Action&lt;/a&gt; and &lt;a href="https://mergejudge.si/guide/run-on-your-machine?utm_source=devto" rel="noopener noreferrer"&gt;runner&lt;/a&gt;, add &lt;code&gt;review.security: true&lt;/code&gt; to &lt;code&gt;.mergejudge.yml&lt;/code&gt; directly.&lt;/p&gt;

&lt;p&gt;When &lt;code&gt;review.security: true&lt;/code&gt; is on, MergeJudge scores five high-severity attack-class criteria alongside the normal rubric (and overrides &lt;code&gt;rubrics.enabled: false&lt;/code&gt; if rubrics were turned off):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criterion ID&lt;/th&gt;
&lt;th&gt;What it checks&lt;/th&gt;
&lt;th&gt;Raises to&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sec.audit.injection&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Untrusted input (request params, headers, webhook/queue payloads, file/env content, model output) reaching a sink unescaped: SQL, shell/exec, &lt;code&gt;eval&lt;/code&gt;, HTML/templates, file paths, redirects, deserialization&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;review&lt;/code&gt; (when confirmed in diff)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sec.audit.authz&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A new or changed route, handler, job or tool acting for a caller without verifying identity and resource ownership (missing auth, IDOR, dropped or moved role check, tenant/owner ID taken from request)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;review&lt;/code&gt; (when confirmed in diff)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sec.audit.secrets-crypto&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Credentials, tokens or keys logged, returned, embedded or committed; weak or home-made crypto (MD5/SHA-1 for passwords, ECB, static IV/salt, &lt;code&gt;Math.random&lt;/code&gt; for tokens, &lt;code&gt;==&lt;/code&gt; on secrets, TLS verification off)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;review&lt;/code&gt; (when confirmed in diff)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sec.audit.callbacks&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inbound webhooks or callbacks skipping signature, token or origin verification; server-side fetches of an attacker-chosen URL, host or redirect target without an allowlist (SSRF, internal addresses, metadata endpoints)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;review&lt;/code&gt; (when confirmed in diff)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sec.audit.ai-tools&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Model output or untrusted text gaining shell, file, network or secret access, or overriding a system prompt, without a check or confirmation &lt;em&gt;(scored only when the diff touches agents, tools, prompts or model calls; otherwise &lt;code&gt;n/a&lt;/code&gt;)&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;review&lt;/code&gt; (when confirmed in diff)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  3. How confirmed and needs-validation findings stop hallucinated blocks
&lt;/h2&gt;

&lt;p&gt;A common failure mode of LLM security reviews is flagging theoretical hardening wishes or guessing about middleware that lives outside the diff. MergeJudge constrains &lt;code&gt;sec.audit.*&lt;/code&gt; in two ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Trust-boundary prompt discipline:&lt;/strong&gt; The prompt instructs the model to fail a criterion &lt;strong&gt;only&lt;/strong&gt; for a real trust-boundary break that the diff introduces or exposes—where attacker-controlled data crosses a boundary without the check that boundary needs. Style, hardening wishes, theory, and code already behind a check are scored &lt;code&gt;pass&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quote verification against the diff:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;❌ &lt;strong&gt;Confirmed (&lt;code&gt;fail&lt;/code&gt;):&lt;/strong&gt; The model copied an exact line from the diff into &lt;code&gt;evidence.quote&lt;/code&gt;, and MergeJudge verified that quote against the diff hunk. A confirmed finding appears with &lt;code&gt;❌&lt;/code&gt; in the &lt;strong&gt;Rubric&lt;/strong&gt; section and raises the pull request lane to &lt;code&gt;review&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;❔ &lt;strong&gt;Needs validation (&lt;code&gt;unverified&lt;/code&gt;):&lt;/strong&gt; The model suspects a trust-boundary break that depends on code outside the diff (for example, whether a router mounts auth middleware upstream) and leaves the quote empty. MergeJudge lists the finding with &lt;code&gt;❔&lt;/code&gt; (&lt;code&gt;path:line&lt;/code&gt; and &lt;code&gt;"Title: why"&lt;/code&gt;) so a human can check it, &lt;strong&gt;leaves the lane unchanged&lt;/strong&gt;, and &lt;strong&gt;keeps &lt;a href="https://mergejudge.si/guide/how-it-works?utm_source=devto#low-risk-code-auto-opt-in" rel="noopener noreferrer"&gt;low-risk code auto&lt;/a&gt; off&lt;/strong&gt; for that pull request.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  4. Pair security mode with &lt;code&gt;context&lt;/code&gt; or &lt;code&gt;deep&lt;/code&gt; mode for larger PRs
&lt;/h2&gt;

&lt;p&gt;The five &lt;code&gt;sec.audit.*&lt;/code&gt; criteria add &lt;strong&gt;about 500 tokens&lt;/strong&gt; to every review prompt, counted against &lt;code&gt;budget.max_tokens_per_pr&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free AI tier (public repositories with no key configured):&lt;/strong&gt; Keeps its usual token, diff-size, and monthly review limits; nothing is raised for security mode.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Larger pull requests or cross-file checks:&lt;/strong&gt; Because &lt;code&gt;diff&lt;/code&gt; mode only shows changed hunks, an auth check or sanitizer defined in another file may look unverified (&lt;code&gt;❔&lt;/code&gt;) in &lt;code&gt;diff&lt;/code&gt; mode. For larger pull requests or deeper passes where the reviewer should inspect callers and imports, run with your own provider key in &lt;code&gt;context&lt;/code&gt; mode or use a &lt;a href="https://mergejudge.si/guide/run-on-your-machine?utm_source=devto" rel="noopener noreferrer"&gt;runner on your machine&lt;/a&gt; or the &lt;a href="https://mergejudge.si/guide/self-host-github-action?utm_source=devto" rel="noopener noreferrer"&gt;GitHub Action&lt;/a&gt; in &lt;code&gt;deep&lt;/code&gt; mode.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How do I turn on security review mode in MergeJudge?
&lt;/h3&gt;

&lt;p&gt;Set &lt;code&gt;review.security: true&lt;/code&gt; in &lt;code&gt;.mergejudge.yml&lt;/code&gt; on your repository's default branch, or toggle the &lt;strong&gt;Security review&lt;/strong&gt; switch in the MergeJudge panel under &lt;strong&gt;Set up&lt;/strong&gt; or &lt;strong&gt;Edit settings&lt;/strong&gt; and merge the resulting pull request. It is off by default, and only a real boolean &lt;code&gt;true&lt;/code&gt; turns it on.&lt;/p&gt;

&lt;h3&gt;
  
  
  What does MergeJudge's security review mode check?
&lt;/h3&gt;

&lt;p&gt;When &lt;code&gt;review.security: true&lt;/code&gt; is set, MergeJudge scores five high-severity attack-class criteria alongside its normal rubric: &lt;code&gt;sec.audit.injection&lt;/code&gt; (untrusted input reaching SQL, shell, eval, HTML, path, redirect or deserialization sinks), &lt;code&gt;sec.audit.authz&lt;/code&gt; (missing authentication, IDOR or dropped role/tenant checks), &lt;code&gt;sec.audit.secrets-crypto&lt;/code&gt; (leaked credentials, weak hashes or ciphers, &lt;code&gt;==&lt;/code&gt; on secrets, disabled TLS verification), &lt;code&gt;sec.audit.callbacks&lt;/code&gt; (unverified webhooks or SSRF), and &lt;code&gt;sec.audit.ai-tools&lt;/code&gt; (untrusted text or model output gaining shell, file, network or secret access when the diff touches agents, tools or prompts).&lt;/p&gt;

&lt;h3&gt;
  
  
  How does MergeJudge avoid hallucinated security failures raising the lane?
&lt;/h3&gt;

&lt;p&gt;Every high-severity rubric failure must include an exact quote that MergeJudge verifies against the pull request diff. A finding with a verified diff quote is marked &lt;strong&gt;confirmed&lt;/strong&gt; (&lt;code&gt;❌&lt;/code&gt;) and raises the lane to &lt;code&gt;review&lt;/code&gt;. If the model suspects a trust-boundary break that depends on code outside the diff and cannot quote a changed line, MergeJudge lists it with a question-mark icon (&lt;code&gt;❔&lt;/code&gt;) as &lt;strong&gt;needs validation&lt;/strong&gt;: it leaves the lane unchanged so a human can check it, while still keeping opt-in &lt;code&gt;lanes.code_auto&lt;/code&gt; off for that pull request.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can a pull request turn off &lt;code&gt;review.security: true&lt;/code&gt; in its own diff?
&lt;/h3&gt;

&lt;p&gt;No. MergeJudge always reads &lt;code&gt;.mergejudge.yml&lt;/code&gt; and policy files such as &lt;code&gt;AGENTS.md&lt;/code&gt; and &lt;code&gt;REVIEW_POLICY.md&lt;/code&gt; from the pull request's base branch tip, never from the pull request head. Any pull request that edits &lt;code&gt;.mergejudge.yml&lt;/code&gt; is placed in the &lt;code&gt;review&lt;/code&gt; lane.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does security review mode increase the free AI tier limits?
&lt;/h3&gt;

&lt;p&gt;No. The five &lt;code&gt;sec.audit.*&lt;/code&gt; criteria add about 500 tokens to every review prompt and count against &lt;code&gt;budget.max_tokens_per_pr&lt;/code&gt;. The free AI tier on public repositories keeps its usual token, diff-size and monthly review caps. For larger pull requests or deeper cross-file checks, use the &lt;a href="https://mergejudge.si/guide/run-on-your-machine?utm_source=devto" rel="noopener noreferrer"&gt;open-source runner&lt;/a&gt; on your machine or your own &lt;a href="https://mergejudge.si/guide/providers?utm_source=devto" rel="noopener noreferrer"&gt;provider API key&lt;/a&gt;.&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Full guide &amp;amp; rubric reference:&lt;/strong&gt; &lt;a href="https://mergejudge.si/guide/ai-security-code-review-github?utm_source=devto" rel="noopener noreferrer"&gt;mergejudge.si/guide/ai-security-code-review-github&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security rubric criteria (&lt;code&gt;sec.audit.*&lt;/code&gt;):&lt;/strong&gt; &lt;a href="https://mergejudge.si/guide/rubrics?utm_source=devto#security-review-mode-optional" rel="noopener noreferrer"&gt;mergejudge.si/guide/rubrics&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open-source runner &amp;amp; GitHub Action (MIT):&lt;/strong&gt; &lt;a href="https://github.com/gauravsharmaGG/mergejudge-runner" rel="noopener noreferrer"&gt;github.com/gauravsharmaGG/mergejudge-runner&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>github</category>
      <category>security</category>
      <category>ai</category>
      <category>codereview</category>
    </item>
    <item>
      <title>How to gate AI agent pull requests on GitHub (without reading every line)</title>
      <dc:creator>Gaurav Sharma</dc:creator>
      <pubDate>Sat, 24 Oct 2026 09:26:11 +0000</pubDate>
      <link>https://dev.to/gauravsharmagg/how-to-gate-ai-agent-pull-requests-on-github-without-reading-every-line-nfk</link>
      <guid>https://dev.to/gauravsharmagg/how-to-gate-ai-agent-pull-requests-on-github-without-reading-every-line-nfk</guid>
      <description>&lt;p&gt;Coding agents open more pull requests than people can read line by line. The goal isn't to read less — it's to spend human attention on the PRs that actually need it, and to make sure no agent can merge, or loosen the review rules, on its own.&lt;/p&gt;

&lt;p&gt;If "good enough to merge" means "whatever the model thinks today", you get noisy line comments, and nothing stops an agent PR from quietly editing the instructions or workflow files it's reviewed with.&lt;/p&gt;

&lt;p&gt;This walkthrough sets up AI pull request review where the repository holds the rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Deterministic rules put every PR in a lane: &lt;code&gt;auto&lt;/code&gt; (low risk), &lt;code&gt;review&lt;/code&gt; (a human must look) or &lt;code&gt;block&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;An AI model reads the diff and adds line comments, but can only make the lane stricter, never looser.&lt;/li&gt;
&lt;li&gt;The rules and policy are read from the base branch, never from the PR branch.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'll use &lt;a href="https://mergejudge.si/?utm_source=devto" rel="noopener noreferrer"&gt;MergeJudge&lt;/a&gt;, an AI pull request reviewer with an open-source (MIT) engine I built for this, as the example. Disclosure up front: it's my project. The core ideas — base-branch config, a deterministic rules floor, and human-merged rule changes — carry over to any setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real examples on GitHub (no install needed)
&lt;/h2&gt;

&lt;p&gt;Before setting anything up, you can see what the output looks like on three real PRs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;auto&lt;/code&gt; (small docs typo): &lt;a href="https://github.com/gauravsharmaGG/mergejudge-demo/pull/2" rel="noopener noreferrer"&gt;https://github.com/gauravsharmaGG/mergejudge-demo/pull/2&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;review&lt;/code&gt; (workflow file change): &lt;a href="https://github.com/gauravsharmaGG/mergejudge-demo/pull/3" rel="noopener noreferrer"&gt;https://github.com/gauravsharmaGG/mergejudge-demo/pull/3&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;block&lt;/code&gt; (hard-coded API key): &lt;a href="https://github.com/gauravsharmaGG/mergejudge-demo/pull/4" rel="noopener noreferrer"&gt;https://github.com/gauravsharmaGG/mergejudge-demo/pull/4&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Option A: Two-click GitHub App (free AI reviews on public repos)
&lt;/h2&gt;

&lt;p&gt;If you don't want to manage YAML or keys first, install the GitHub App from &lt;a href="https://mergejudge.si/guide/cloud?utm_source=devto" rel="noopener noreferrer"&gt;https://mergejudge.si/guide/cloud?utm_source=devto&lt;/a&gt;. Public repositories get up to 10 free AI reviews per month out of the box with no API key and no config file. For private repos or higher volume, bring your own key or run the local CLI runner (&lt;code&gt;npx mergejudge-runner setup&lt;/code&gt;), which uses your existing Claude Code or Codex login.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option B: Self-hosted GitHub Action (no MergeJudge account)
&lt;/h2&gt;

&lt;p&gt;If you want everything to run inside your own GitHub Actions runner with no MergeJudge account:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Add your provider key as a repo secret
&lt;/h3&gt;

&lt;p&gt;Pick Anthropic, OpenAI, z.ai or any OpenAI-compatible endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh secret &lt;span class="nb"&gt;set &lt;/span&gt;AI_API_KEY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Or set &lt;code&gt;provider: none&lt;/code&gt; to run deterministic rules only with no key.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Add &lt;code&gt;.github/workflows/mergejudge.yml&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MergeJudge&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;opened&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;synchronize&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;reopened&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;ready_for_review&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;labeled&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;unlabeled&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;
  &lt;span class="na"&gt;pull-requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
  &lt;span class="na"&gt;checks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;lane&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github.event.pull_request.head.repo.full_name == github.repository&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gauravsharmaGG/mergejudge-runner@v1&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;AI_API_KEY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AI_API_KEY }}&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;anthropic&lt;/span&gt;        &lt;span class="c1"&gt;# or openai, zai, openai-compatible, none&lt;/span&gt;
          &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;claude-sonnet-4-5&lt;/span&gt;   &lt;span class="c1"&gt;# any model your provider supports&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open a PR and you get one sticky summary comment, a &lt;code&gt;mergejudge/lane&lt;/code&gt; check (&lt;code&gt;success&lt;/code&gt; = auto, &lt;code&gt;neutral&lt;/code&gt; = review, &lt;code&gt;failure&lt;/code&gt; = block) and inline comments on the diff.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hold a pull request with a label
&lt;/h3&gt;

&lt;p&gt;The GitHub Action workflow includes &lt;code&gt;labeled&lt;/code&gt; and &lt;code&gt;unlabeled&lt;/code&gt;, so a hold applies without a new push:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;opened&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;synchronize&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;reopened&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;ready_for_review&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;labeled&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;unlabeled&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Labels can only raise a lane. Adding &lt;code&gt;needs-review&lt;/code&gt; or &lt;code&gt;do-not-merge&lt;/code&gt; holds a pull request, and removing it sends the pull request back to its rule and AI lane. Anyone with GitHub triage access can remove it, so treat triage access as hold authority. Label changes reuse the cached verdict for that commit, so they never re-run the model.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Put non-negotiable paths in &lt;code&gt;.mergejudge.yml&lt;/code&gt; on your default branch
&lt;/h3&gt;

&lt;p&gt;Anything that always requires a human — like &lt;code&gt;.github/**&lt;/code&gt;, auth, or database migrations — shouldn't depend on a prompt noticing it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;lanes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;protected&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.github/**"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;deploy/**"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;**/auth/**"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;**/migrations/**"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Protected paths always land in at least &lt;code&gt;review&lt;/code&gt;, with or without an AI provider. Because &lt;code&gt;.mergejudge.yml&lt;/code&gt; and &lt;code&gt;AGENTS.md&lt;/code&gt; are read from the base branch tip, a PR opened by an agent cannot weaken the rules for its own review.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Put judgement rules in &lt;code&gt;AGENTS.md&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;If you already keep an &lt;code&gt;AGENTS.md&lt;/code&gt; or &lt;code&gt;CLAUDE.md&lt;/code&gt; in your repo for coding agents, add a &lt;code&gt;## Code review&lt;/code&gt; section in plain English (for example, "Every new HTTP handler under &lt;code&gt;src/api/&lt;/code&gt; must check resource authorization"). MergeJudge reads it from the base branch and uses it to raise the lane when violated.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this setup does not do
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It doesn't merge PRs automatically — &lt;code&gt;auto&lt;/code&gt; is a low-risk signal, not a guarantee, and human branch protection stays in charge.&lt;/li&gt;
&lt;li&gt;It doesn't replace a full secret scanner (the secret check on added lines is a fast screen).&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When an AI provider is enabled, the diff and context snippets are sent to that provider under your key.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Source &amp;amp; Action: &lt;a href="https://github.com/gauravsharmaGG/mergejudge-runner" rel="noopener noreferrer"&gt;https://github.com/gauravsharmaGG/mergejudge-runner&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Marketplace: &lt;a href="https://github.com/marketplace/actions/mergejudge-ai-code-review" rel="noopener noreferrer"&gt;https://github.com/marketplace/actions/mergejudge-ai-code-review&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Docs &amp;amp; guides: &lt;a href="https://mergejudge.si/?utm_source=devto" rel="noopener noreferrer"&gt;https://mergejudge.si/?utm_source=devto&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>github</category>
      <category>ai</category>
      <category>devops</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
