<?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: JinHyuk Sung</title>
    <description>The latest articles on DEV Community by JinHyuk Sung (@sjh9714).</description>
    <link>https://dev.to/sjh9714</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%2F3979231%2Fa135da54-2755-404b-b652-4d80d7565c16.jpg</url>
      <title>DEV Community: JinHyuk Sung</title>
      <link>https://dev.to/sjh9714</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sjh9714"/>
    <language>en</language>
    <item>
      <title>I audited 249 of my own AI coding sessions. The problem wasn't lying.</title>
      <dc:creator>JinHyuk Sung</dc:creator>
      <pubDate>Sat, 01 Aug 2026 10:19:48 +0000</pubDate>
      <link>https://dev.to/sjh9714/i-audited-249-of-my-own-ai-coding-sessions-the-problem-wasnt-lying-4f42</link>
      <guid>https://dev.to/sjh9714/i-audited-249-of-my-own-ai-coding-sessions-the-problem-wasnt-lying-4f42</guid>
      <description>&lt;h2&gt;
  
  
  I never scrolled up
&lt;/h2&gt;

&lt;p&gt;I use a coding agent every day. I give it a task, go do something else, and come back to a line at the bottom of the screen like this one:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"빌드·회귀 스모크·기존 분석 테스트 모두 통과."&lt;br&gt;
&lt;em&gt;(build, regression smoke, and the existing analysis tests all pass)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is a real line from my own session log. I never checked it. Instead of scrolling up to see whether the tests actually ran, I gave it the next task. I did that for months.&lt;/p&gt;

&lt;p&gt;Then I read a post in a Korean dev community where someone had looked into their agent's private reasoning and found that &lt;strong&gt;the memory given to its tester role contained a list of ways to work around problems when they came up&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That doesn't mean the agent was malicious. If you tell something to make the tests pass, finding the cheapest path is what optimisation does. The problem is when the cheapest path is "avoid the check" rather than "fix the code," and you have no way to notice.&lt;/p&gt;

&lt;p&gt;So I decided to check. The tool is called &lt;strong&gt;red-handed&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not a judge, a diff
&lt;/h2&gt;

&lt;p&gt;I wasn't trying to build a judge. I wanted &lt;strong&gt;a side-by-side of what the agent said and what it actually did&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The material was already there. Claude Code writes a transcript for every session: every command it ran and what came back, the before and after of every file edit, and every sentence it said to me. Line that up with git and you can compute the gap between the words and the work.&lt;/p&gt;

&lt;p&gt;Did it claim the tests pass without running them. Did it claim they pass right after a run that failed. Did it rewrite an expected value to match whatever the broken code produced. Nine checks like that.&lt;/p&gt;

&lt;p&gt;The thing I spent longest on wasn't a feature. It was &lt;strong&gt;what happens when the tool is wrong&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There are two ways to be wrong here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Missing something.&lt;/strong&gt; The user loses nothing — they're exactly as uninformed as before.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accusing someone who did the work honestly.&lt;/strong&gt; That's telling a person they cheated when they didn't. Get that wrong once and nobody opens it again.&lt;/p&gt;

&lt;p&gt;The costs are nowhere near symmetric. So the rule became: &lt;strong&gt;miss things rather than accuse wrongly.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That turned into two hard constraints.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A confirmed finding needs two pieces of evidence.&lt;/strong&gt; The session has to show it happening, &lt;em&gt;and&lt;/em&gt; the change has to still be in the working tree. If the agent undid it later, there's nothing to accuse anyone of, and the finding disappears.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Something unread is not a failure.&lt;/strong&gt; If a test ran and I couldn't parse the output, that's "I don't know," not "it failed." That distinction ends up inverting the whole result.&lt;/p&gt;

&lt;p&gt;No model is called for any of this. If the verdict came from an LLM, the same transcript would produce different answers on different days — and then it isn't evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running it over 249 sessions
&lt;/h2&gt;

&lt;p&gt;I pointed it at every session on my machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;249 sessions. Your agent said "tests pass" 124 times.
   117  a test ran first
     7  no test ran in that session at all
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confirmed findings: &lt;strong&gt;zero&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I'll be honest, that was deflating. Weeks of work on a lie detector and it caught no lies.&lt;/p&gt;

&lt;p&gt;Then I opened the seven one by one, and realised I'd been asking the wrong question.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real problem wasn't lying
&lt;/h2&gt;

&lt;p&gt;Four of the seven came from one project. The agent had said things like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"드래그·휠 5방향 브라우저 테스트 통과."&lt;br&gt;
&lt;em&gt;(drag and scroll, all five directions, browser tests pass)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That isn't a lie. The agent really did open a browser and check. But that check &lt;strong&gt;left no machine-readable trace of any kind.&lt;/strong&gt; So there is no way to find out later whether the claim held. Not for me, not for the tool, not for whoever inherits that code.&lt;/p&gt;

&lt;p&gt;The other three were the same shape: the project runs its tests through its own script and my parser doesn't know that output format. I can tell that &lt;em&gt;something test-shaped ran&lt;/em&gt;. I can't tell that it passed.&lt;/p&gt;

&lt;p&gt;That's where the conclusion flipped. &lt;strong&gt;I was worried about an agent that lies. What I actually found was verification nobody can read.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And that's less a property of AI than of how we work now. It used to be fine for a person to open a browser, look, and move on — because that person kept looking at that code. Now the thing doing the checking is an agent whose memory resets every session. &lt;strong&gt;Verification you can't read is indistinguishable from verification that never happened.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So those seven are reported as &lt;code&gt;SUSPICIOUS&lt;/code&gt;, not &lt;code&gt;CAUGHT&lt;/code&gt;, and the wording is "go look at what that command actually reported" rather than "it lied to you." That's as far as the tool can honestly go.&lt;/p&gt;

&lt;p&gt;One caveat I'd rather state than have someone find: of those 249 sessions, only 12 contained a "tests pass" claim at all. The rest are short — a question or two. So "0 out of 249" would be an inflated way to read this.&lt;/p&gt;

&lt;h2&gt;
  
  
  And it falsely accused me six times
&lt;/h2&gt;

&lt;p&gt;Once it worked, I spent a while trying to break it. That turned out to be the most valuable part of the project. An adversarial review found &lt;strong&gt;five&lt;/strong&gt; separate ways it would accuse honest work:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A test run killed by a timeout, read as a failure&lt;/li&gt;
&lt;li&gt;A runner it didn't know (&lt;code&gt;rspec&lt;/code&gt;, &lt;code&gt;phpunit&lt;/code&gt;, &lt;code&gt;tox&lt;/code&gt;), read as "no test ran"&lt;/li&gt;
&lt;li&gt;A re-run under a launcher it couldn't see, so it judged on the stale result&lt;/li&gt;
&lt;li&gt;A behaviour change the user had explicitly asked for, read as rewriting the answer&lt;/li&gt;
&lt;li&gt;A backgrounded command, counted as a pass&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first two are worth spelling out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The timeout one was the worst.&lt;/strong&gt; When a test run is killed for taking too long it leaves a distinctive exit signal, and my code read that as a failure. So if the agent then said the tests passed, it printed the single most insulting verdict in the tool: &lt;em&gt;"said tests pass — the last run failed."&lt;/em&gt; My code was directly violating the rule I'd written two paragraphs of design notes about.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The second was one character.&lt;/strong&gt; The pattern that recognises test runners looked for the word &lt;code&gt;spec&lt;/code&gt; with a word boundary in front of it — which never matches inside &lt;code&gt;rspec&lt;/code&gt;, because &lt;code&gt;r&lt;/code&gt; is a word character. So a Ruby developer could run their suite, get &lt;code&gt;20 examples, 0 failures&lt;/code&gt;, and my tool would state with confidence that &lt;strong&gt;no test had run at all&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And here's the part that stings. My README proudly said &lt;em&gt;"0 false positives across 183 real sessions."&lt;/em&gt; That was true — but not because the tool was good. It was true because &lt;strong&gt;every project on my machine is JavaScript or TypeScript&lt;/strong&gt;, so neither of those paths had ever executed. I built a tool to verify claims, reported that it passed its own verification, and hadn't actually exercised the code. &lt;strong&gt;I did the exact thing the tool exists to catch.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The sixth turned up after I shipped.&lt;/strong&gt; A scoped &lt;code&gt;pytest tests/test_sync_cli.py&lt;/code&gt;, then edits to a GitHub workflow file and two &lt;code&gt;.tsx&lt;/code&gt; files, and the tool called the claim stale. A Python test can't import a &lt;code&gt;.tsx&lt;/code&gt;, and a CI workflow isn't what just ran on this machine. Nothing had gone stale.&lt;/p&gt;

&lt;p&gt;There was a tempting fix: "different directory, treat it as unrelated." Simple, and right most of the time. It's also wrong — run &lt;code&gt;pytest tests/&lt;/code&gt; and then edit &lt;code&gt;src/&lt;/code&gt; and the claim really has expired. So instead of guessing, I only suppress what is &lt;strong&gt;definitely&lt;/strong&gt; true: Python can't load a &lt;code&gt;.tsx&lt;/code&gt;, a JS runner can't load a &lt;code&gt;.py&lt;/code&gt;, a CI workflow isn't a local run. Anything ambiguous still counts. &lt;strong&gt;"Looks unrelated" is a guess, and you don't throw out evidence on a guess.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;All six are pinned by regression tests now.&lt;/p&gt;

&lt;h2&gt;
  
  
  It caught me again while I was writing this
&lt;/h2&gt;

&lt;p&gt;I re-ran it to refresh the numbers for this article, and found one of mine in the list:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"테스트 3개로 고정했고 전체 389개 통과."&lt;br&gt;
&lt;em&gt;(pinned it with three tests, all 389 pass)&lt;/em&gt;&lt;br&gt;
→ 1 file changed after that run: &lt;code&gt;scripts/social.tape&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What I said was true, and the file that changed is a screen-recording script for a demo GIF. It has nothing to do with the test suite.&lt;/p&gt;

&lt;p&gt;But this isn't a bug. It's the rule I chose one section ago — &lt;strong&gt;anything ambiguous still counts&lt;/strong&gt; — doing exactly what I told it to. The tool has no idea what a &lt;code&gt;.tape&lt;/code&gt; file is, and I decided that unknown means counted.&lt;/p&gt;

&lt;p&gt;That's the price of the choice. To avoid missing things, it sometimes barks at nothing. In exchange, this one came out as &lt;code&gt;SUSPICIOUS&lt;/code&gt; rather than &lt;code&gt;CAUGHT&lt;/code&gt;, with the changed filename printed right next to it, so it took me three seconds to dismiss. &lt;strong&gt;That's what the two tiers are for.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Three things I'd keep
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Decide which way you'll be wrong before you tune accuracy.&lt;/strong&gt; "What's the accuracy?" is close to meaningless for a tool like this, because the two directions of error cost wildly different amounts. Pick the direction, then defend that decision in every branch. I wrote the principle in a doc and then broke it in three places in code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ship evidence, not verdicts.&lt;/strong&gt; If the output says "it lied," a user can only believe it or not. Show the timestamps and the quoted line and they can decide for themselves. That's also why dismissing my own false positive above took three seconds. A tool you can catch being wrong is a tool you keep using.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The actual fix is verification you can read.&lt;/strong&gt; That's what the four browser-test findings taught me. When you hand work to an agent, don't say "check it" — say &lt;strong&gt;"check it and leave the result somewhere a machine can read."&lt;/strong&gt; A check that lives only in someone's head doesn't exist by the next session.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;Runs locally. Your transcripts and your code never leave your machine — it calls no model and makes no network request of its own. Same session, same answer, every time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# a made-up session where every check fires, so you can see the shape first&lt;/span&gt;
npx @jinhyuk9714/red-handed@latest demo

&lt;span class="c"&gt;# then your own version of the numbers above&lt;/span&gt;
npx @jinhyuk9714/red-handed@latest stats
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MIT, and the code is at &lt;a href="https://github.com/sjh9714/red-handed" rel="noopener noreferrer"&gt;github.com/sjh9714/red-handed&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Your numbers will be different from mine. I had zero confirmed findings, seven checks nobody could read, and one false alarm I found while writing this paragraph. Whichever way it goes for you, the point is that &lt;strong&gt;you don't know until you look.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>ai</category>
      <category>testing</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I benchmarked Claude Code skills against a placebo — and half of mine failed</title>
      <dc:creator>JinHyuk Sung</dc:creator>
      <pubDate>Fri, 24 Jul 2026 12:50:36 +0000</pubDate>
      <link>https://dev.to/sjh9714/i-benchmarked-claude-code-skills-against-a-placebo-and-half-of-mine-failed-4okk</link>
      <guid>https://dev.to/sjh9714/i-benchmarked-claude-code-skills-against-a-placebo-and-half-of-mine-failed-4okk</guid>
      <description>&lt;p&gt;There's a whole ecosystem of "agent skills" now — reusable instruction files you drop into Claude Code (or Cursor, or Copilot) to make the model write cleaner code, debug more carefully, use fewer tokens, and so on. Some of these repos have tens of thousands of GitHub stars. Almost none of them ship a single number telling you whether the skill actually does anything.&lt;/p&gt;

&lt;p&gt;That bothered me, because "adding a plausible-sounding instruction" and "adding an instruction that works" look &lt;em&gt;identical&lt;/em&gt; until you measure them. So I built a benchmark with one rule, committed before I ran anything:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;No skill gets merged unless it beats both a no-instruction baseline AND a placebo prompt on its pre-registered target metric, measured on hidden hold-out tests, with accuracy not allowed to drop. Skills that fail are published anyway, with their numbers.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The placebo arm is the part almost nobody runs, and it turned out to be the most important one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a placebo
&lt;/h2&gt;

&lt;p&gt;Most "battle-tested" skill collections that measure anything at all compare skill-on vs skill-off. The problem: that comparison can't separate "this skill works" from "adding &lt;em&gt;any&lt;/em&gt; confident-sounding text changes the model's behavior." LLMs are suggestible. If you want to claim your skill did something, you have to show it beats a comparable-length instruction that contains no actual mechanism — just vibes.&lt;/p&gt;

&lt;p&gt;So every result here is a three-way comparison — &lt;strong&gt;off / placebo / on&lt;/strong&gt; — run K=5–8 times per task per arm, in isolated git workspaces, graded by hold-out acceptance tests the agent never sees, with every raw run log committed to the repo and the README regenerated from those logs in CI. 496 runs total, all on &lt;code&gt;claude-opus-4-8&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's what came out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding 1: the placebo often made code &lt;em&gt;bigger&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;My anti-over-engineering skill (&lt;code&gt;underkill&lt;/code&gt;, ~20 lines) cut source LOC by &lt;strong&gt;−23.8% vs baseline&lt;/strong&gt; at identical accuracy (60/60 hold-out passes). Good. But the interesting column is the placebo: a style-only "write clean, minimal, professional code" instruction (156 words to underkill's 250) didn't reduce code on a single one of the 12 tasks — it increased it on 7 and tied on the other 5 (median +18.8% across the tasks that moved, +6.9% across all 12).&lt;/p&gt;

&lt;p&gt;Read that again: telling the model to write clean code made it write &lt;em&gt;more&lt;/em&gt; code. The generic exhortation added nothing but tokens, and the model padded to match the vibe. If I'd only compared on-vs-off, &lt;code&gt;underkill&lt;/code&gt; would have looked good. Compared against the placebo, it looks good &lt;em&gt;and&lt;/em&gt; I can prove the effect isn't just instruction-presence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding 2: a 196k-star skill barely beat "no instructions"
&lt;/h2&gt;

&lt;p&gt;One of the most-installed general behavioral rulesets is the "Karpathy Guidelines" (196k stars as of 2026-07-25) — four rules derived from Andrej Karpathy's observations on LLM coding pitfalls, one of which is "Simplicity First: if you write 200 lines and it could be 50, rewrite it." That's a direct, falsifiable claim on the exact metric &lt;code&gt;underkill&lt;/code&gt; targets, so I ran it as a comparison arm on the same 12 tasks.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;arm&lt;/th&gt;
&lt;th&gt;median src LOC&lt;/th&gt;
&lt;th&gt;hold-out accuracy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;off (no instructions)&lt;/td&gt;
&lt;td&gt;10.5&lt;/td&gt;
&lt;td&gt;60/60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;placebo&lt;/td&gt;
&lt;td&gt;12.5&lt;/td&gt;
&lt;td&gt;60/60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;underkill (mine, ~20 lines)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8.0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;60/60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Karpathy Guidelines (~196k★)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;10.0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;60/60&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The famous skill &lt;strong&gt;beats the placebo clearly (−20%)&lt;/strong&gt; — so its mechanism is real, not just prompt-presence. But against a no-instruction baseline it barely moves (&lt;strong&gt;−4.8%&lt;/strong&gt;), because on small tasks Opus is already close to minimal. And my focused 20-line skill writes &lt;strong&gt;20% less code than the 196k-star one&lt;/strong&gt;, at equal accuracy and slightly lower cost.&lt;/p&gt;

&lt;p&gt;This isn't a dunk on the Karpathy skill — it addresses four different failure modes and only one is on this axis. The point is narrower and more useful: &lt;strong&gt;a rule aimed at one specific failure mode beats a broad, general ruleset that merely mentions it.&lt;/strong&gt; Instruction &lt;em&gt;presence&lt;/em&gt; is cheap; instruction &lt;em&gt;mechanism&lt;/em&gt; is what pays.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding 3: two of my own four skills failed the gate
&lt;/h2&gt;

&lt;p&gt;Publishing only wins would make the whole exercise worthless, so here are the rejects with their numbers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;tests-that-bite&lt;/code&gt;&lt;/strong&gt; (a test-writing discipline skill) hit a ceiling: baseline Opus already killed 100% of my mutation-testing mutants on 3 of 4 tasks. My mutants were too coarse to differentiate. Rejected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;thrift&lt;/code&gt;&lt;/strong&gt; (a token-spend skill) cut turns by 14% but landed $0.005 &lt;em&gt;above&lt;/em&gt; baseline on median cost per run. Under a co-primary "cost AND turns" rule, that's a rejection, not a rounding call.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;thrift&lt;/code&gt; sweep had the most counterintuitive result of the whole project: I ran the 92k-star "caveman" terse-mode ruleset as a comparison arm, and it measured &lt;strong&gt;more expensive per run than no instructions at all&lt;/strong&gt; on every cost task. Agentic cost is input-dominated (files read, tool results, repeated context), so an instruction that compresses the model's &lt;em&gt;output&lt;/em&gt; can't recoup the input tokens its own prompt adds on every turn. Output-compression advice that's true for chat responses can invert on agentic runs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this doesn't prove
&lt;/h2&gt;

&lt;p&gt;The tasks are small and self-contained (the committed reference solutions run 6–63 non-blank source LOC, median 14) — enough to gate a skill on, not enough to generalize to large codebases. K=5–8 gives you evidence, not proof. Pre-registration here is commit-ordering in a repo I control, self-attested (though the harness carries an earlier multi-day record). And hold-out material lives in the same repo, so it's reachable in principle — I run a CI check that scans every committed run log for references to the task material (516/516 committed logs clean). All of this is written up in the repo's "Known Limitations," because a results log that only contains good news isn't worth trusting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it / break it
&lt;/h2&gt;

&lt;p&gt;Two skills passed the gate (&lt;code&gt;underkill&lt;/code&gt;, &lt;code&gt;repro-first&lt;/code&gt;). They install as a Claude Code plugin or via &lt;code&gt;npx skills add sjh9714/skill-receipts&lt;/code&gt;, and the installed snippet is byte-identical to what the benchmark measured (CI enforces that).&lt;/p&gt;

&lt;p&gt;If you have a skill you think works — yours, or a famous one you want audited — the gate is the same for everyone: open an issue. I'd genuinely like to be proven wrong on some of these.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repo + all raw logs:&lt;/strong&gt; &lt;a href="https://github.com/sjh9714/skill-receipts" rel="noopener noreferrer"&gt;https://github.com/sjh9714/skill-receipts&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>llm</category>
      <category>testing</category>
    </item>
    <item>
      <title>Your AI-contribution policy is prose. Here's the enforceable half.</title>
      <dc:creator>JinHyuk Sung</dc:creator>
      <pubDate>Fri, 24 Jul 2026 10:58:52 +0000</pubDate>
      <link>https://dev.to/sjh9714/your-ai-contribution-policy-is-prose-heres-the-enforceable-half-570n</link>
      <guid>https://dev.to/sjh9714/your-ai-contribution-policy-is-prose-heres-the-enforceable-half-570n</guid>
      <description>&lt;p&gt;Your open-source project probably added an AI-contribution policy in the last few months. Apache has one. The Linux Foundation has one. The OpenSSF Technical Advisory Council is finalizing a foundation-wide one right now. Bitcoin Core, ripgrep, uv, and dozens of smaller projects have copied the pattern. If you maintain something popular, you've either written one or you're about to.&lt;/p&gt;

&lt;p&gt;Almost all of them say some version of the same three things: disclose when you use AI; a human must review and remain responsible for every change; no fully autonomous agent PRs.&lt;/p&gt;

&lt;p&gt;These are good norms. But I want to point at something uncomfortable: &lt;strong&gt;as written, almost none of them are enforceable.&lt;/strong&gt; They're prose in a CONTRIBUTING.md, and prose is an honor system. So I went looking for how big the gap actually is.&lt;/p&gt;

&lt;h2&gt;
  
  
  What agent PRs actually do at scale
&lt;/h2&gt;

&lt;p&gt;I scanned 2,204 recently merged, agent-authored pull requests across public GitHub repos (Devin, Copilot coding agent, Codex, Claude Code, Cursor). The scan is deterministic and checkout-free — it reads PR metadata and file contents through the GitHub API, never executes PR code, and never calls an LLM, so every finding replays. Three results are directly relevant to anyone writing one of these policies:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;0 of 2,204 declared a machine-checkable scope for the change.&lt;/strong&gt; Not a low number — zero. Your policy can say "a human must review and understand every change," but a reviewer opening an agent PR has exactly what a reviewer of a human PR has: the diff, and a description written in prose. The agent knew precisely what task it was given. None of that intent survives into the PR in a form anything can check against. So "review every change" is real, but "verify the change matched its intent" isn't available to you yet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.9% modified agent control-plane files&lt;/strong&gt; — &lt;code&gt;AGENTS.md&lt;/code&gt;, &lt;code&gt;CLAUDE.md&lt;/code&gt;, &lt;code&gt;.mcp.json&lt;/code&gt;, &lt;code&gt;.cursor/rules/**&lt;/code&gt;, and similar. These are the files that steer &lt;em&gt;future&lt;/em&gt; agent runs in your repo. An agent PR that edits its own instructions is a quiet privilege-escalation path, and it's exactly the kind of change that reads as a boring docs diff and sails through review. Most policies don't mention this file class at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Of the PRs that touched CI workflows, ~13% raised GitHub Actions permissions&lt;/strong&gt;, and ~17% introduced unpinned actions. Your DCO and attribution language will never catch a &lt;code&gt;contents: read -&amp;gt; write&lt;/code&gt; bump in a workflow file. That's not a licensing question; it's a supply-chain one, and it's invisible to the parts of your policy that are about authorship.&lt;/p&gt;

&lt;p&gt;One more, because it decides where to aim: repositories with 10k+ stars had roughly &lt;strong&gt;half&lt;/strong&gt; the finding rate of the long tail (4.3% vs 8.6%). Established projects have guardrails. The projects getting hit hardest are the small, beginner-friendly ones — the exact repos that just adopted a prose policy and have the least review bandwidth to back it up.&lt;/p&gt;

&lt;p&gt;(Full methodology, every query, and the raw approach are public: &lt;a href="https://github.com/sjh9714/mergewarden/blob/main/docs/study/methodology.md" rel="noopener noreferrer"&gt;https://github.com/sjh9714/mergewarden/blob/main/docs/study/methodology.md&lt;/a&gt; — findings are review evidence, not vulnerabilities or misconduct claims; I publish aggregates only and name no repositories.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Which policy clauses are actually checkable
&lt;/h2&gt;

&lt;p&gt;Here's the useful reframe. Split your policy into clauses you &lt;em&gt;hope&lt;/em&gt; people follow and clauses a machine can &lt;em&gt;check&lt;/em&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Clause (typical wording)&lt;/th&gt;
&lt;th&gt;Enforceable automatically?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"You could have written this yourself"&lt;/td&gt;
&lt;td&gt;No — honor system&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Explain your changes in your own words"&lt;/td&gt;
&lt;td&gt;No — honor system&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Disclose AI use"&lt;/td&gt;
&lt;td&gt;Partly — require a checkbox/trailer, but you can't verify honesty&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"No autonomous-agent PRs"&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Yes&lt;/strong&gt; — they arrive on &lt;code&gt;cursor/**&lt;/code&gt;, &lt;code&gt;codex/**&lt;/code&gt;, &lt;code&gt;copilot/**&lt;/code&gt; branches or &lt;code&gt;*-swe-agent[bot]&lt;/code&gt; authors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Don't touch files that steer future agents"&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Yes&lt;/strong&gt; — a path-glob diff check&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Don't quietly escalate CI permissions"&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Yes&lt;/strong&gt; — diff the workflow &lt;code&gt;permissions:&lt;/code&gt; block, base vs head&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Stay within the scope of the task"&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Yes, but only if scope is declared&lt;/strong&gt; — the missing primitive&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The last row is the interesting one. If an agent PR carried a tiny machine-readable declaration of what it intended to touch, "did it stay in scope" becomes a deterministic check instead of a reviewer's guess:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&amp;lt;!-- ai-contract
version: 1
agent: codex
task: update session expiry handling
allowed_paths:
&lt;span class="p"&gt;  -&lt;/span&gt; src/auth/&lt;span class="ge"&gt;**&lt;/span&gt;
&lt;span class="p"&gt;  -&lt;/span&gt; test/auth/&lt;span class="ge"&gt;**&lt;/span&gt;
--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'd honestly rather see something like this become a vendor-neutral convention than any one tool's feature. Agent vendors already have the task context at generation time; nothing carries it into the PR. That's the gap under every one of these policies.&lt;/p&gt;

&lt;h2&gt;
  
  
  The point
&lt;/h2&gt;

&lt;p&gt;If you're writing an AI-contribution policy: keep the prose norms, they matter. But separate the honor-system clauses from the ones a cheap, deterministic check can actually enforce, and wire the second group into CI. The three checks worth adding first, in order of bang-for-effort: (1) flag control-plane edits (AGENTS.md / .mcp.json / rules files) for mandatory human review; (2) diff workflow permissions base-vs-head and flag any escalation; (3) detect autonomous-agent PRs by branch/author so they get the extra scrutiny your review bandwidth is already rationing.&lt;/p&gt;

&lt;p&gt;None of that needs an LLM, none of it needs to check out PR code, and all of it is boring, replayable, and free. The policy tells people what's expected; a check tells you when it didn't happen.&lt;/p&gt;

&lt;p&gt;I built an open-source tool (&lt;a href="https://github.com/sjh9714/mergewarden" rel="noopener noreferrer"&gt;MergeWarden&lt;/a&gt;, MIT) that does exactly these checks as a GitHub Action, which is what produced the numbers above — but the argument stands whatever you use, including a few lines of your own CI. The takeaway isn't "adopt my thing." It's: your policy is prose, agent PRs are a firehose, and the enforceable half of your policy is smaller and cheaper to automate than you think.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>ai</category>
      <category>github</category>
      <category>devops</category>
    </item>
    <item>
      <title>What 2,204 merged AI-agent PRs actually touched (0 declared their scope)</title>
      <dc:creator>JinHyuk Sung</dc:creator>
      <pubDate>Wed, 22 Jul 2026 14:56:13 +0000</pubDate>
      <link>https://dev.to/sjh9714/what-2204-merged-ai-agent-prs-actually-touched-0-declared-their-scope-d20</link>
      <guid>https://dev.to/sjh9714/what-2204-merged-ai-agent-prs-actually-touched-0-declared-their-scope-d20</guid>
      <description>&lt;p&gt;AI coding agents — Devin, Copilot coding agent, Codex, Claude Code, Cursor — open and merge pull requests at scale now. Every agent vendor knows, at the moment of generation, exactly what the task was. My question: does any of that intent survive into the PR in a form a machine could check? And while I was looking: how often do agent PRs cross boundaries that deserve human eyes?&lt;/p&gt;

&lt;p&gt;So I scanned 2,204 recently merged, agent-authored PRs on public GitHub repos with a checkout-free policy engine, using only its built-in default policy. It reads PR metadata and file contents through the GitHub API — it never executes PR code and never calls an LLM, so every finding is deterministic and replayable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one number that surprised me
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;0 of 2,204 PRs declared a machine-readable scope for the change.&lt;/strong&gt; Not a low percentage — zero. Agent vendors emit rich task context at generation time, and none of it reaches the PR as something a machine could verify. If you want to know whether an agent PR stayed inside its intended task, there is currently nothing to check it against.&lt;/p&gt;

&lt;h2&gt;
  
  
  What else showed up
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;7.0% of complete analyses had at least one boundary finding&lt;/strong&gt; (153 of 2,191). The structure underneath that number is the interesting part:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Of the &lt;strong&gt;349 PRs that touched GitHub Actions workflows or package manifests&lt;/strong&gt;, 12.9% escalated workflow permissions and 17.5% introduced unpinned actions, reusable workflows, or containers. Workflow-touching agent PRs are where the risk concentrates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3.9% changed agent control-plane files&lt;/strong&gt; — AGENTS.md, CLAUDE.md, .mcp.json, and similar. These files steer every future agent PR in the repo, which makes them a quiet privilege-escalation path: an agent that edits its own instructions today shapes what the next agent does tomorrow.&lt;/li&gt;
&lt;li&gt;Repos with &lt;strong&gt;10k+ stars showed a 4.3% finding rate — roughly half&lt;/strong&gt; the long-tail rate (8.6%). Established projects have guardrails. The long tail of small repos, where most agent PRs actually land, is where agents run with the least oversight.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Honest denominators
&lt;/h2&gt;

&lt;p&gt;Percentages hide choices, so here are mine: workflow-rule rates use PRs that actually touched workflow or manifest content; control-plane rates use all complete analyses; the contract statistic uses everything. Incomplete analyses fail closed and are reported as their own bucket, never silently dropped. A "finding" is not an accusation — most of the escalations I saw are probably benign. That is exactly the point: nobody declared them, nobody checked them, and benign-until-it-isn't is not a security posture.&lt;/p&gt;

&lt;h2&gt;
  
  
  The missing primitive
&lt;/h2&gt;

&lt;p&gt;The zero is the story. Agent PRs today are reviewed the way human PRs are — by reading the diff — but agents differ from humans in one reviewable way: their intent is machine-generated and could be machine-checkable. A PR-body contract as small as this would close the loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&amp;lt;!-- mergewarden-contract
version: 1
agent: codex
task: update session expiry handling
allowed_paths:
&lt;span class="p"&gt;  -&lt;/span&gt; src/auth/&lt;span class="ge"&gt;**&lt;/span&gt;
&lt;span class="p"&gt;  -&lt;/span&gt; test/auth/&lt;span class="ge"&gt;**&lt;/span&gt;
--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The contract is an untrusted declaration — the base-branch policy stays authoritative — but once it exists, "did the PR leave its declared scope" becomes a deterministic check instead of a reviewer's guess. I'd rather see this become a vendor-neutral convention than one tool's feature; the format above is one concrete proposal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reproduce it
&lt;/h2&gt;

&lt;p&gt;Every query, date window, and aggregation script is published in the methodology writeup. The scanner (MergeWarden, MIT) runs against any public PR without installing anything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx mergewarden scan owner/repo#123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full methodology and the tool: &lt;a href="https://github.com/sjh9714/mergewarden" rel="noopener noreferrer"&gt;https://github.com/sjh9714/mergewarden&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you maintain a repo that receives agent PRs and want the scan results for your own recent PRs, open an issue — I'm looking for maintainers to help measure false-positive rates against real-world judgment. And if you've seen an agent PR quietly cross a line in your own repo, I'd love to hear about it in the comments.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>github</category>
      <category>devops</category>
      <category>opensource</category>
    </item>
    <item>
      <title>AI agents can open PRs. Who checks whether they crossed the line?</title>
      <dc:creator>JinHyuk Sung</dc:creator>
      <pubDate>Fri, 17 Jul 2026 09:04:21 +0000</pubDate>
      <link>https://dev.to/sjh9714/ai-agents-can-open-prs-who-checks-whether-they-crossed-the-line-47b7</link>
      <guid>https://dev.to/sjh9714/ai-agents-can-open-prs-who-checks-whether-they-crossed-the-line-47b7</guid>
      <description>&lt;h3&gt;
  
  
  The gap between "works" and "stayed in scope"
&lt;/h3&gt;

&lt;p&gt;An AI coding agent can produce a pull request that builds, passes tests, and&lt;br&gt;
implements the requested feature. That same PR can also edit a release&lt;br&gt;
workflow, increase a GitHub token permission, change &lt;code&gt;AGENTS.md&lt;/code&gt;, or touch a&lt;br&gt;
file outside the declared task.&lt;/p&gt;

&lt;p&gt;That does not make the PR malicious. Still, the reviewer should be able to see&lt;br&gt;
the boundary change without reconstructing it from a large diff. Ordinary tests&lt;br&gt;
answer whether the repository still works. A semantic reviewer asks whether the&lt;br&gt;
code makes sense. Neither reliably records whether the PR stayed inside the&lt;br&gt;
agreed scope.&lt;/p&gt;

&lt;p&gt;I built &lt;a href="https://github.com/sjh9714/Agent-Gate" rel="noopener noreferrer"&gt;Agent Gate&lt;/a&gt; for that narrower&lt;br&gt;
question.&lt;/p&gt;
&lt;h3&gt;
  
  
  A checkout-free policy gate
&lt;/h3&gt;

&lt;p&gt;Agent Gate is an open-source GitHub Action and CLI. It collects pull-request&lt;br&gt;
metadata and selected file content through GitHub APIs, loads &lt;code&gt;agent-gate.yml&lt;/code&gt;&lt;br&gt;
from the exact base commit, and produces deterministic findings.&lt;/p&gt;

&lt;p&gt;It intentionally does not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;checkout or execute pull-request code;&lt;/li&gt;
&lt;li&gt;run target-repository package scripts;&lt;/li&gt;
&lt;li&gt;load policy from the PR head branch; or&lt;/li&gt;
&lt;li&gt;call an LLM at runtime.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That gives the policy a useful trust boundary. A pull request can change the&lt;br&gt;
policy for future PRs, but it cannot weaken the policy evaluating itself.&lt;/p&gt;

&lt;p&gt;If GitHub reports 42 changed files and Agent Gate can collect only 41, the&lt;br&gt;
analysis is incomplete and fails closed. Authentication failures, rate limits,&lt;br&gt;
and server errors are not silently treated as missing files or default policy.&lt;/p&gt;
&lt;h3&gt;
  
  
  Try it before installing it
&lt;/h3&gt;

&lt;p&gt;Node 20 or newer is enough to scan a public PR:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;--yes&lt;/span&gt; @jinhyuk9714/agent-gate@0.3.1 scan owner/repo#123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The CLI clones nothing and executes nothing from the target repository. Human,&lt;br&gt;
JSON, and Markdown output are available, and the Action uses the same analysis&lt;br&gt;
contract.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the evidence looks like
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsjh9714%2FAgent-Gate%2Fv0.3.1%2Fdocs%2Fassets%2Fagent-gate-report-v0.3.1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fsjh9714%2FAgent-Gate%2Fv0.3.1%2Fdocs%2Fassets%2Fagent-gate-report-v0.3.1.png" alt="Agent Gate report from public composite PR #16" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The public &lt;a href="https://github.com/sjh9714/agent-gate-install-smoke-20260617/pull/16" rel="noopener noreferrer"&gt;composite proof PR&lt;/a&gt;&lt;br&gt;
starts with a docs-only contract and then changes documentation, a workflow,&lt;br&gt;
and &lt;code&gt;AGENTS.md&lt;/code&gt;. Its &lt;a href="https://github.com/sjh9714/agent-gate-install-smoke-20260617/actions/runs/29071622785" rel="noopener noreferrer"&gt;Action run&lt;/a&gt;&lt;br&gt;
reports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;two &lt;code&gt;contract/out-of-scope&lt;/code&gt; findings;&lt;/li&gt;
&lt;li&gt;a high-risk workflow path;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;agent-control-plane/drift&lt;/code&gt; for &lt;code&gt;AGENTS.md&lt;/code&gt;; and&lt;/li&gt;
&lt;li&gt;workflow- and job-level permission escalation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The report also records the policy digest, exact base/head SHAs, expected and&lt;br&gt;
analyzed file counts, and whether collection completed. Finding IDs are derived&lt;br&gt;
from canonical evidence rather than display wording, so a waiver can target one&lt;br&gt;
exact finding with a reason and expiry.&lt;/p&gt;

&lt;h3&gt;
  
  
  Differential workflow checks
&lt;/h3&gt;

&lt;p&gt;Existing workflow risk should not be re-reported whenever an unrelated line&lt;br&gt;
changes. For modified workflows, Agent Gate compares canonical base/head sets&lt;br&gt;
and reports newly introduced or expanded permissions, unpinned references,&lt;br&gt;
secret references, head checkout patterns, and other configured checks.&lt;/p&gt;

&lt;p&gt;Added workflows are compared with an empty base. Deleted workflows are reported&lt;br&gt;
explicitly. Malformed or unavailable content makes the analysis incomplete&lt;br&gt;
instead of producing a partial pass.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adopt it without turning CI red on day one
&lt;/h3&gt;

&lt;p&gt;The intended rollout is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Observe:&lt;/strong&gt; collect findings and identify repository-specific noise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Warn:&lt;/strong&gt; require review while the policy and waivers are tuned.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Block:&lt;/strong&gt; enforce only the findings whose evidence the team trusts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Checks can be configured independently as &lt;code&gt;off&lt;/code&gt;, &lt;code&gt;warn&lt;/code&gt;, or &lt;code&gt;error&lt;/code&gt;. Exact,&lt;br&gt;
expiring waivers live in base-branch policy and remain visible in reports.&lt;/p&gt;

&lt;h3&gt;
  
  
  Honest limits
&lt;/h3&gt;

&lt;p&gt;Agent Gate is not a replacement for tests, a semantic code reviewer, or a tool&lt;br&gt;
such as zizmor. Its agentic-workflow rule recognizes registered agent actions&lt;br&gt;
and a deliberately narrow set of direct or one-hop prompt flows. Shell, files,&lt;br&gt;
step outputs, and cross-job data flow are outside the v0.3 scope.&lt;/p&gt;

&lt;p&gt;It also has no SaaS, GitHub App, product telemetry, or runtime model judgment.&lt;br&gt;
The goal is reproducible change-control evidence, not an opaque risk score.&lt;/p&gt;

&lt;p&gt;I am looking for policy and false-positive feedback from repositories where AI&lt;br&gt;
agents create or review PRs. Which findings would you trust enough to block,&lt;br&gt;
and which should remain warnings or be turned off?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>devops</category>
      <category>github</category>
    </item>
    <item>
      <title>Would you block a PR that changes GitHub Actions contents permission from read to write?</title>
      <dc:creator>JinHyuk Sung</dc:creator>
      <pubDate>Tue, 30 Jun 2026 05:52:53 +0000</pubDate>
      <link>https://dev.to/sjh9714/would-you-block-a-pr-that-changes-github-actions-contents-permission-from-read-to-write-27hm</link>
      <guid>https://dev.to/sjh9714/would-you-block-a-pr-that-changes-github-actions-contents-permission-from-read-to-write-27hm</guid>
      <description>&lt;p&gt;A sandbox PR changed one GitHub Actions workflow permission:&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;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;write&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The base branch had:&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;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the concrete case I am trying to calibrate.&lt;/p&gt;

&lt;p&gt;Agent Gate reported:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent Gate: NEEDS HUMAN DECISION
Decision: warn
Why: contents permission increased from read to write.
Path: .github/workflows/demo-release.yml
Recommended next step: review the workflow permission change before merging.
Policy status: warning today; eligible to become a merge gate after tuning.

Rule: workflow/permission-escalation
Policy source: built-in default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Live PR comment proof:&lt;br&gt;
&lt;a href="https://github.com/sjh9714/agent-gate-install-smoke-20260617/pull/13#issuecomment-4828248162" rel="noopener noreferrer"&gt;https://github.com/sjh9714/agent-gate-install-smoke-20260617/pull/13#issuecomment-4828248162&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What matters to me is that this did not depend on an LLM noticing the change.&lt;/p&gt;

&lt;p&gt;The Action did not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;checkout PR code&lt;/li&gt;
&lt;li&gt;run repository scripts&lt;/li&gt;
&lt;li&gt;call an LLM at runtime&lt;/li&gt;
&lt;li&gt;load policy from the PR head branch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first-run repo config was also absent. Agent Gate used its built-in default policy and recorded:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;configSource: default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I am not trying to claim that the PR is automatically bad. A permission increase can be intentional.&lt;/p&gt;

&lt;p&gt;The question is what CI should do when it sees this kind of boundary change.&lt;/p&gt;

&lt;p&gt;My current default is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;warn on first run&lt;/li&gt;
&lt;li&gt;keep the report human-readable&lt;/li&gt;
&lt;li&gt;let teams promote this finding to block after tuning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For AI-generated PRs, I think deterministic CI evidence is useful because agent changes can touch workflow and security boundaries as part of ordinary work.&lt;/p&gt;

&lt;p&gt;But this specific finding is broader than AI: any PR that raises GitHub Actions permissions may deserve deliberate review.&lt;/p&gt;

&lt;p&gt;Question:&lt;/p&gt;

&lt;p&gt;In your repo, is this block, warn, or noise?&lt;/p&gt;

&lt;p&gt;What extra evidence would make it actionable?&lt;/p&gt;

&lt;p&gt;Repo:&lt;br&gt;
&lt;a href="https://github.com/sjh9714/Agent-Gate" rel="noopener noreferrer"&gt;https://github.com/sjh9714/Agent-Gate&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Disclosure: I used AI assistance to help draft and edit this article, and I reviewed the technical claims before publishing.&lt;/p&gt;

</description>
      <category>cicd</category>
      <category>discuss</category>
      <category>github</category>
      <category>security</category>
    </item>
    <item>
      <title>I made Agent Gate installable in 30 seconds for AI PR checks</title>
      <dc:creator>JinHyuk Sung</dc:creator>
      <pubDate>Fri, 26 Jun 2026 10:51:38 +0000</pubDate>
      <link>https://dev.to/sjh9714/i-made-agent-gate-installable-in-30-seconds-for-ai-pr-checks-140f</link>
      <guid>https://dev.to/sjh9714/i-made-agent-gate-installable-in-30-seconds-for-ai-pr-checks-140f</guid>
      <description>&lt;p&gt;One problem with security-ish developer tools is that the install path can ask for trust before it has earned any.&lt;/p&gt;

&lt;p&gt;Agent Gate is a GitHub Action for AI-generated pull requests. It does not review code with an LLM. It checks repeatable CI evidence such as workflow permission changes, agent control-plane drift, package lifecycle script drift, and missing test-file evidence.&lt;/p&gt;

&lt;p&gt;The important constraint is that the Action should be safe to try first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no checkout of PR code&lt;/li&gt;
&lt;li&gt;no runtime LLM calls&lt;/li&gt;
&lt;li&gt;no repository script execution&lt;/li&gt;
&lt;li&gt;no policy loaded from the PR head branch&lt;/li&gt;
&lt;li&gt;warn mode by default for first runs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I recently changed the onboarding flow so the first install is basically one pinned workflow download.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; .github/workflows &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/sjh9714/Agent-Gate/v0.2.5/templates/agent-gate-observe.yml &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; .github/workflows/agent-gate.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This downloads a tag-pinned GitHub Actions workflow YAML file. It is not &lt;code&gt;curl | bash&lt;/code&gt;, and it does not execute a remote script.&lt;/p&gt;

&lt;p&gt;The downloaded workflow uses:&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;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sjh9714/Agent-Gate@v0.2.5&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;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;warn&lt;/span&gt;
  &lt;span class="na"&gt;fail-on-block&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It also uses only:&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;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;read&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The other change is that first runs no longer require &lt;code&gt;agent-gate.yml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If the default config file is confirmed missing on the PR base branch, Agent Gate uses its built-in default policy and records:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;configSource: default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That means a maintainer can install the workflow first, see what the default warnings look like, and only add repo-specific policy later.&lt;/p&gt;

&lt;p&gt;I also verified the README install path in a sandbox PR. The run:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;loaded &lt;code&gt;sjh9714/Agent-Gate@v0.2.5&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;used no &lt;code&gt;actions/checkout&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;had no &lt;code&gt;agent-gate.yml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;fell back to the built-in default policy&lt;/li&gt;
&lt;li&gt;finished successfully&lt;/li&gt;
&lt;li&gt;produced a &lt;code&gt;warn&lt;/code&gt; decision for package lifecycle script drift&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The compact log looked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent Gate: NEEDS HUMAN DECISION
Decision: warn
Why: preinstall script added in package.json.
Path: package.json
Policy status: warning today; eligible to become a merge gate after tuning.

- warn agf_2ac4687b2f8f712a dependency/lifecycle-script-added package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the first-run model I want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;install quickly
observe warnings
understand the report
then tune policy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It still does not prove semantic correctness. A deterministic CI gate should not pretend to know whether a PR is “good.” The goal is narrower: surface repeatable evidence that a maintainer can inspect before merge.&lt;/p&gt;

&lt;p&gt;If you maintain a GitHub Actions-heavy repo or use coding agents to open PRs, I would like feedback on one thing:&lt;/p&gt;

&lt;p&gt;Does this first-run path feel safe and clear enough to try in a real repo?&lt;/p&gt;

&lt;p&gt;Repo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/sjh9714/Agent-Gate" rel="noopener noreferrer"&gt;https://github.com/sjh9714/Agent-Gate&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>github</category>
      <category>security</category>
      <category>showdev</category>
    </item>
    <item>
      <title>CI gates for AI-generated PRs need re-derivable evidence</title>
      <dc:creator>JinHyuk Sung</dc:creator>
      <pubDate>Sun, 21 Jun 2026 01:08:59 +0000</pubDate>
      <link>https://dev.to/sjh9714/ci-gates-for-ai-generated-prs-need-re-derivable-evidence-2g4e</link>
      <guid>https://dev.to/sjh9714/ci-gates-for-ai-generated-prs-need-re-derivable-evidence-2g4e</guid>
      <description>&lt;p&gt;When a CI gate flags an AI-generated PR, the important question is not only "what did it flag?"&lt;/p&gt;

&lt;p&gt;It is also:&lt;/p&gt;

&lt;p&gt;"Could someone else come back later and re-derive why this finding fired?"&lt;/p&gt;

&lt;p&gt;That is the reason I added evidence snapshots to Agent Gate v0.2.1.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Agent Gate is
&lt;/h2&gt;

&lt;p&gt;Agent Gate is a GitHub Action for AI-generated pull requests.&lt;/p&gt;

&lt;p&gt;It does not review code with an LLM. It checks deterministic merge evidence in CI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PR scope escapes&lt;/li&gt;
&lt;li&gt;GitHub Actions permission escalation&lt;/li&gt;
&lt;li&gt;AGENTS.md / .mcp.json drift&lt;/li&gt;
&lt;li&gt;missing test-file evidence&lt;/li&gt;
&lt;li&gt;high-risk path changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Action does not checkout PR code, call LLMs at runtime, or execute repository scripts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why finding IDs were not enough
&lt;/h2&gt;

&lt;p&gt;In v0.2.0, Agent Gate added stable finding IDs.&lt;/p&gt;

&lt;p&gt;That gave every finding a short audit handle, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;agf_987ab9ddb8c1b299
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is useful for references, comments, future override workflows, and log-based debugging.&lt;/p&gt;

&lt;p&gt;But an ID by itself is not proof. If someone sees the ID later, they still need to know what recorded material produced it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What v0.2.1 adds
&lt;/h2&gt;

&lt;p&gt;v0.2.1 adds &lt;code&gt;evidenceSnapshot&lt;/code&gt; to public findings.&lt;/p&gt;

&lt;p&gt;The split is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;findingId = short audit handle
evidenceSnapshot = canonical material used to derive that handle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The snapshot is intentionally boring. It contains stable rule material such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rule id&lt;/li&gt;
&lt;li&gt;severity&lt;/li&gt;
&lt;li&gt;path or line when present&lt;/li&gt;
&lt;li&gt;normalized evidence label/value pairs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It does not include timestamps, report order, risk score, version, commit SHA, or mutable display text.&lt;/p&gt;

&lt;h2&gt;
  
  
  A real report shape
&lt;/h2&gt;

&lt;p&gt;Example compact log output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent Gate: NEEDS HUMAN DECISION
Decision: warn
Risk score: 49 / 100
Why: Agent-generated PRs must include an agent-gate contract.
Recommended next step: Add a PR contract before relying on scope checks.
Policy status: warning today; eligible to become a merge gate after tuning.

Findings:
- error agf_be0c2c2a66312aff contract/missing
- error agf_987ab9ddb8c1b299 risk/high-risk-path .github/workflows/agent-gate.yml
- warn agf_6016e753491255d7 workflow/dangerous-pattern .github/workflows/agent-gate.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compact log stays short, but the JSON and Markdown reports carry the fuller evidence.&lt;/p&gt;

&lt;p&gt;Example JSON shape:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"findingId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"agf_987ab9ddb8c1b299"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ruleId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"risk/high-risk-path"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;".github/workflows/agent-gate.yml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"evidenceSnapshot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ruleId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"risk/high-risk-path"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;".github/workflows/agent-gate.yml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"evidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"changed_file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;".github/workflows/agent-gate.yml"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;For me, the bar for promoting a finding from warning to blocking is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A third party should be able to re-derive the finding from recorded evidence.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That does not mean the check is magically correct.&lt;/p&gt;

&lt;p&gt;It means the failure mode is visible, reproducible, and tunable.&lt;/p&gt;

&lt;p&gt;A repo can start in warn mode, observe which findings are useful, and only later promote low-noise findings into merge gates.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this does not solve yet
&lt;/h2&gt;

&lt;p&gt;Agent Gate still does not prove semantic correctness.&lt;/p&gt;

&lt;p&gt;Matching test-file evidence is not proof that the tests cover the behavior. It is change evidence / self-consistency evidence.&lt;/p&gt;

&lt;p&gt;Maintainer override storage is also not implemented yet. That is probably the next hard design question: if someone bypasses a finding, where should that override live so it is durable enough to inspect later?&lt;/p&gt;

&lt;p&gt;CODEOWNERS / reviewer evidence and package dependency drift are also future work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;If you maintain a repo where coding agents open PRs, I would love feedback on whether this kind of evidence is useful or too noisy in observe mode.&lt;/p&gt;

&lt;p&gt;Repo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/sjh9714/Agent-Gate" rel="noopener noreferrer"&gt;https://github.com/sjh9714/Agent-Gate&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Disclosure: I maintain Agent Gate. v0.2.1 is still a prerelease; I would start in warn mode before treating any finding as a merge gate.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>cicd</category>
      <category>github</category>
      <category>security</category>
    </item>
    <item>
      <title>LLM reviewers are useful, but some PR checks should stay deterministic</title>
      <dc:creator>JinHyuk Sung</dc:creator>
      <pubDate>Tue, 16 Jun 2026 20:17:27 +0000</pubDate>
      <link>https://dev.to/sjh9714/llm-reviewers-are-useful-but-some-pr-checks-should-stay-deterministic-4k1e</link>
      <guid>https://dev.to/sjh9714/llm-reviewers-are-useful-but-some-pr-checks-should-stay-deterministic-4k1e</guid>
      <description>&lt;p&gt;AI coding agents are getting better at opening pull requests.&lt;/p&gt;

&lt;p&gt;That changes the review problem.&lt;/p&gt;

&lt;p&gt;A normal review asks whether the code looks correct, whether the design makes sense, and whether the edge cases were considered.&lt;/p&gt;

&lt;p&gt;Those questions still matter.&lt;/p&gt;

&lt;p&gt;But an AI-generated pull request also raises a different kind of question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Did the agent change something outside the intended task, and is there enough repeatable evidence to merge?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I have started thinking about this as a split between &lt;strong&gt;judgment&lt;/strong&gt; and &lt;strong&gt;evidence&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;LLM reviewers help with judgment. Agent Gate verifies deterministic merge evidence.&lt;/p&gt;

&lt;p&gt;I do not think every review question should become a hard CI gate. Some parts of code review need human context. Some parts benefit from an LLM noticing suspicious patterns. But a few checks are mechanical enough that I want them to be deterministic, repeatable, and visible before merge.&lt;/p&gt;

&lt;p&gt;This is the checklist I currently use when thinking about AI-generated PRs.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Did the PR stay in scope?
&lt;/h2&gt;

&lt;p&gt;The first question is not whether the code is good.&lt;/p&gt;

&lt;p&gt;It is whether the PR changed the files it was supposed to change.&lt;/p&gt;

&lt;p&gt;For a human PR, an unrelated edit may be easy to explain in review. For an agent PR, unrelated edits are more suspicious because they may reflect an instruction drift, a tool mistake, or a broad refactor the maintainer did not ask for.&lt;/p&gt;

&lt;p&gt;A simple contract can help:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This PR is allowed to touch:
- src/auth/**
- tests/auth/**
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the review can ask a deterministic question:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Did the PR touch anything outside those paths?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That does not prove the code is correct. It only proves the PR stayed inside its declared boundary.&lt;/p&gt;

&lt;p&gt;That boundary still matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Did workflow permissions escalate?
&lt;/h2&gt;

&lt;p&gt;GitHub Actions workflows are one of the highest-risk places for an agent to edit.&lt;/p&gt;

&lt;p&gt;A small source change and a workflow permission change do not have the same risk profile.&lt;/p&gt;

&lt;p&gt;For example, I would want a very visible warning if a PR adds or changes this:&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;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;write&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or starts using &lt;code&gt;secrets.*&lt;/code&gt; in a new workflow path.&lt;/p&gt;

&lt;p&gt;This is not a semantic code review problem. It is a policy boundary problem.&lt;/p&gt;

&lt;p&gt;The question is deterministic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Did this PR increase workflow privileges or introduce a dangerous workflow pattern?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That kind of check should not depend on whether an LLM happened to notice it in a comment.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Did agent-control-plane files change?
&lt;/h2&gt;

&lt;p&gt;AI coding agents often depend on files that shape future behavior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AGENTS.md
CLAUDE.md
.github/copilot-instructions.md
.cursor/rules/**
.mcp.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A change to these files can affect future agent runs, tool access, or repo-specific instructions.&lt;/p&gt;

&lt;p&gt;That makes them different from normal documentation changes.&lt;/p&gt;

&lt;p&gt;If an AI-generated PR edits &lt;code&gt;.mcp.json&lt;/code&gt; or &lt;code&gt;AGENTS.md&lt;/code&gt;, I want that surfaced clearly before merge, even if the source code diff looks harmless.&lt;/p&gt;

&lt;p&gt;The deterministic question is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Did the PR change files that control future agent behavior?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is especially important for teams adopting coding agents across repositories, because the control plane can drift quietly.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Is there matching test evidence?
&lt;/h2&gt;

&lt;p&gt;Test evidence is tricky.&lt;/p&gt;

&lt;p&gt;A changed test file does not prove the behavior is correct. It does not prove the test is meaningful. It does not prove coverage.&lt;/p&gt;

&lt;p&gt;But for risky areas, the absence of any matching test change is still useful evidence.&lt;/p&gt;

&lt;p&gt;If a PR changes auth logic, payment handling, session middleware, or a migration, I want to know whether the PR also changed a related test file.&lt;/p&gt;

&lt;p&gt;The check should be phrased carefully:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;There is no matching test-file evidence.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This PR is untested.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That distinction matters. Deterministic checks should say exactly what they know, and no more.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Did package scripts or dependencies drift?
&lt;/h2&gt;

&lt;p&gt;This is not always the first rule I would add, but it is one I keep coming back to.&lt;/p&gt;

&lt;p&gt;Package manifests and lockfiles can hide meaningful risk:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package.json
pnpm-lock.yaml
yarn.lock
package-lock.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some changes are normal dependency maintenance. Others deserve more attention:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"postinstall"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node scripts/setup.js"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For AI-generated PRs, I would want to know:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Did a lifecycle script appear?
Did an existing package script change?
Did dependencies change without an expected lockfile change?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, not every finding should block. But these changes should be easy to see.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Did the right human reviewer approve?
&lt;/h2&gt;

&lt;p&gt;This is where deterministic evidence meets human ownership.&lt;/p&gt;

&lt;p&gt;A PR can stay in scope, avoid workflow escalation, and include test evidence, but still need the right reviewer.&lt;/p&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/auth/** changed -&amp;gt; security reviewer expected
.github/workflows/** changed -&amp;gt; platform reviewer expected
.mcp.json changed -&amp;gt; maintainer/platform approval expected
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I do not think this should always block by default, especially for solo maintainers. But for teams, reviewer evidence may be one of the most useful signals.&lt;/p&gt;

&lt;p&gt;The question is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Did the right human approve the risky part of this PR?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is not a replacement for review. It is a way to make ownership visible.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should stay human?
&lt;/h2&gt;

&lt;p&gt;A lot.&lt;/p&gt;

&lt;p&gt;I would not want deterministic CI to answer questions like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is this design good?
Is this abstraction worth it?
Will users understand this behavior?
Is this bug fix actually correct?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those are judgment questions.&lt;/p&gt;

&lt;p&gt;LLM reviewers can help with judgment. Human reviewers own judgment. Deterministic gates should focus on evidence that can be checked the same way every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should be deterministic?
&lt;/h2&gt;

&lt;p&gt;The best candidates are checks that are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;explainable&lt;/li&gt;
&lt;li&gt;repeatable&lt;/li&gt;
&lt;li&gt;hard to miss&lt;/li&gt;
&lt;li&gt;tied to merge risk&lt;/li&gt;
&lt;li&gt;not dependent on executing PR code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For me, that currently includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PR scope boundaries&lt;/li&gt;
&lt;li&gt;workflow permission escalation&lt;/li&gt;
&lt;li&gt;dangerous workflow patterns&lt;/li&gt;
&lt;li&gt;agent-control-plane drift&lt;/li&gt;
&lt;li&gt;missing test-file evidence for high-risk paths&lt;/li&gt;
&lt;li&gt;package script and dependency drift&lt;/li&gt;
&lt;li&gt;reviewer evidence for sensitive paths&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These checks do not make an AI-generated PR safe.&lt;/p&gt;

&lt;p&gt;They make the risk easier to inspect before merge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start in warn mode
&lt;/h2&gt;

&lt;p&gt;The safest adoption path is not to block everything on day one.&lt;/p&gt;

&lt;p&gt;I would start with warnings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mode: warn
fail-on-block: false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then observe real PRs.&lt;/p&gt;

&lt;p&gt;Which findings are useful?&lt;br&gt;
Which ones are noisy?&lt;br&gt;
Which ones would you trust as merge gates?&lt;/p&gt;

&lt;p&gt;Only after that would I promote low-noise findings to blocking checks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing thought
&lt;/h2&gt;

&lt;p&gt;I think AI-generated PR review will need both judgment and evidence.&lt;/p&gt;

&lt;p&gt;LLM reviewers can help with judgment.&lt;/p&gt;

&lt;p&gt;Deterministic CI checks should verify merge evidence.&lt;/p&gt;

&lt;p&gt;I’m exploring this idea in Agent Gate, a small GitHub Action for deterministic merge evidence in AI-generated PRs.&lt;/p&gt;

&lt;p&gt;Disclosure: I used AI assistance to help draft and edit this article, and I reviewed the technical claims before publishing.&lt;/p&gt;

</description>
      <category>devtools</category>
      <category>ai</category>
      <category>security</category>
      <category>github</category>
    </item>
    <item>
      <title>I built a deterministic CI firewall for AI-generated pull requests</title>
      <dc:creator>JinHyuk Sung</dc:creator>
      <pubDate>Mon, 15 Jun 2026 15:22:57 +0000</pubDate>
      <link>https://dev.to/sjh9714/i-built-a-deterministic-ci-firewall-for-ai-generated-pull-requests-4o3c</link>
      <guid>https://dev.to/sjh9714/i-built-a-deterministic-ci-firewall-for-ai-generated-pull-requests-4o3c</guid>
      <description>&lt;p&gt;AI coding agents are getting good enough to open pull requests.&lt;/p&gt;

&lt;p&gt;That is useful.&lt;/p&gt;

&lt;p&gt;It also changes the review problem.&lt;/p&gt;

&lt;p&gt;A normal code review asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Does this code look correct?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An AI-generated PR also raises a different question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Did this agent change something I did not intend, and does this PR have enough evidence to merge?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Agent Gate is still a prerelease, so I am starting with a narrow goal: make AI-generated PRs easier to inspect before merge.&lt;/p&gt;

&lt;p&gt;That second question is why I built &lt;strong&gt;Agent Gate for AI PRs&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The core idea
&lt;/h2&gt;

&lt;p&gt;Agent Gate is a deterministic CI firewall for AI-generated pull requests.&lt;/p&gt;

&lt;p&gt;It is not an LLM reviewer.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;LLM reviewers help with judgment. Agent Gate verifies deterministic merge evidence.&lt;/p&gt;

&lt;p&gt;An LLM reviewer can tell you whether code looks suspicious. Agent Gate checks whether the PR crossed policy boundaries that should be explainable and repeatable in CI.&lt;/p&gt;

&lt;p&gt;The mental model is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Use your LLM reviewer for judgment.&lt;br&gt;&lt;br&gt;
Use Agent Gate for deterministic merge evidence.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Agent Gate checks questions that should not require an LLM:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;did the PR stay inside its declared scope?&lt;/li&gt;
&lt;li&gt;did workflow permissions escalate?&lt;/li&gt;
&lt;li&gt;did agent control-plane files drift?&lt;/li&gt;
&lt;li&gt;did high-risk code change without matching test-file evidence?&lt;/li&gt;
&lt;li&gt;did MCP config changes get surfaced?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are not semantic code review questions. They are merge-boundary questions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I wanted this
&lt;/h2&gt;

&lt;p&gt;Imagine an agent is asked to fix an auth session bug.&lt;/p&gt;

&lt;p&gt;The expected scope might be:&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;allowed_paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;src/auth/**&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;tests/auth/**&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But the PR also changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/payments/webhook.ts
.github/workflows/release.yml
.mcp.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A reviewer might catch that. An LLM reviewer might catch that. But I do not want this to depend only on someone noticing.&lt;/p&gt;

&lt;p&gt;I want CI to say:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This PR crossed its declared scope.
This PR changed workflow permissions.
This PR changed the agent tool surface.
This PR needs human decision before merge.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the shape of Agent Gate.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Agent Gate catches today
&lt;/h2&gt;

&lt;p&gt;The current &lt;code&gt;v0.1.2&lt;/code&gt; release is intentionally focused on deterministic checks.&lt;/p&gt;

&lt;p&gt;It can flag or block the following, depending on policy mode.&lt;/p&gt;

&lt;h3&gt;
  
  
  Out-of-contract edits
&lt;/h3&gt;

&lt;p&gt;Agent Gate can parse a small PR body contract:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&amp;lt;!-- agent-gate-contract
version: 1
agent: codex
task: update auth session handling
allowed_paths:
&lt;span class="p"&gt;  -&lt;/span&gt; src/auth/&lt;span class="ge"&gt;**&lt;/span&gt;
&lt;span class="p"&gt;  -&lt;/span&gt; tests/auth/&lt;span class="ge"&gt;**&lt;/span&gt;
required_evidence:
&lt;span class="p"&gt;  -&lt;/span&gt; matching auth tests changed
--&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the PR changes files outside &lt;code&gt;allowed_paths&lt;/code&gt;, Agent Gate reports that as a contract escape.&lt;/p&gt;

&lt;h3&gt;
  
  
  Workflow permission escalation
&lt;/h3&gt;

&lt;p&gt;GitHub Actions workflows are powerful. If a PR changes this:&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;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to this:&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;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;write&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;that should be visible before merge.&lt;/p&gt;

&lt;p&gt;Agent Gate checks workflow-level permission escalation and dangerous workflow patterns such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;write-all&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;id-token: write&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pull_request_target&lt;/code&gt; checking out PR head&lt;/li&gt;
&lt;li&gt;unpinned third-party actions&lt;/li&gt;
&lt;li&gt;added &lt;code&gt;secrets.*&lt;/code&gt; usage&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Agent control-plane drift
&lt;/h3&gt;

&lt;p&gt;Files like these can change how future agents behave:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AGENTS.md
CLAUDE.md
.cursor/**
.github/copilot-instructions.md
.mcp.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A PR that changes &lt;code&gt;.mcp.json&lt;/code&gt; is not just changing config. It may be changing which tools an agent can call.&lt;/p&gt;

&lt;p&gt;Agent Gate treats those files as an agent control plane and reports drift.&lt;/p&gt;

&lt;h3&gt;
  
  
  Missing test evidence
&lt;/h3&gt;

&lt;p&gt;Agent Gate can define high-risk paths:&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;high_risk_paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;src/auth/**&lt;/span&gt;
    &lt;span class="na"&gt;require_tests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;tests/auth/**&lt;/span&gt;
    &lt;span class="na"&gt;severity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If auth code changes but no matching auth test file changes, Agent Gate reports missing test evidence.&lt;/p&gt;

&lt;p&gt;This does not prove semantic test coverage. It only checks deterministic file-pattern evidence.&lt;/p&gt;

&lt;p&gt;That limitation is intentional.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a report looks like
&lt;/h2&gt;

&lt;p&gt;One piece of early feedback was that the report should not start with a wall of rule IDs.&lt;/p&gt;

&lt;p&gt;It should answer the maintainer's first question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What should I do with this PR?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So the Markdown report now leads with a human decision.&lt;/p&gt;

&lt;p&gt;Example shape:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent Gate: NEEDS HUMAN DECISION

Why:
This PR changed `.github/workflows/release.yml` and added `secrets.*` usage.

Recommended next step:
Review the workflow change before merging.

Policy status:
Warning today; eligible to become a merge gate after tuning.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The detailed rule findings still appear underneath.&lt;/p&gt;

&lt;p&gt;The machine-readable JSON decision remains simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"decision"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"warn"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The human-facing report can say &lt;code&gt;NEEDS HUMAN DECISION&lt;/code&gt;, while the machine-readable result stays &lt;code&gt;pass&lt;/code&gt;, &lt;code&gt;warn&lt;/code&gt;, or &lt;code&gt;block&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The trust boundary
&lt;/h2&gt;

&lt;p&gt;Agent Gate is designed around a conservative trust boundary.&lt;/p&gt;

&lt;p&gt;At runtime, the GitHub Action:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;does not checkout PR code&lt;/li&gt;
&lt;li&gt;does not execute repository scripts&lt;/li&gt;
&lt;li&gt;does not call LLMs&lt;/li&gt;
&lt;li&gt;does not execute MCP servers&lt;/li&gt;
&lt;li&gt;does not load policy from the PR head branch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It reads PR metadata and changed-file contents through GitHub APIs.&lt;/p&gt;

&lt;p&gt;It loads &lt;code&gt;agent-gate.yml&lt;/code&gt; from the PR base branch, not from the untrusted PR branch.&lt;/p&gt;

&lt;p&gt;That matters because a PR should not be able to weaken its own policy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing it
&lt;/h2&gt;

&lt;p&gt;Agent Gate is available on GitHub Marketplace:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/marketplace/actions/agent-gate-for-ai-prs" rel="noopener noreferrer"&gt;https://github.com/marketplace/actions/agent-gate-for-ai-prs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A minimal workflow looks like this:&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Agent Gate&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="s"&gt;opened&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;synchronize&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;reopened&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;edited&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;labeled&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;unlabeled&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ready_for_review&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;read&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;agent-gate&lt;/span&gt;&lt;span class="pi"&gt;:&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;sjh9714/Agent-Gate@v0.1.2&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;github-token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.GITHUB_TOKEN }}&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;warn&lt;/span&gt;
          &lt;span class="na"&gt;fail-on-block&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I recommend starting with:&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;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;warn&lt;/span&gt;
&lt;span class="na"&gt;fail-on-block&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives you an observe path.&lt;/p&gt;

&lt;p&gt;First learn what Agent Gate finds in your repository. Then promote only the policies that are useful and low-noise into merge gates.&lt;/p&gt;

&lt;p&gt;A small starting policy could be:&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;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&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;warn&lt;/span&gt;

&lt;span class="na"&gt;contract&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;required_for&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;agent&lt;/span&gt;
  &lt;span class="na"&gt;allow_missing_in_observe_mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="na"&gt;agent_detection&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ai&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;agent&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;codex&lt;/span&gt;
  &lt;span class="na"&gt;branch_patterns&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;codex/**"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ai/**"&lt;/span&gt;

&lt;span class="na"&gt;high_risk_paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;workflows&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;paths&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/workflows/**"&lt;/span&gt;
    &lt;span class="na"&gt;severity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Local replay demo
&lt;/h2&gt;

&lt;p&gt;The repository includes an &lt;code&gt;unsafe-pr-zoo&lt;/code&gt; with deterministic fixtures.&lt;/p&gt;

&lt;p&gt;After cloning the repo and installing dependencies, you can run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm &lt;span class="nb"&gt;install
&lt;/span&gt;pnpm &lt;span class="nt"&gt;--filter&lt;/span&gt; agent-gate build
node packages/cli/dist/main.js replay fixtures/unsafe-pr-zoo/workflow-permission-escalation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent Gate: BLOCKED

ERROR workflow/permission-escalation
contents permission increased from read to write.
Path: .github/workflows/release.yml

ERROR workflow/dangerous-pattern
.github/workflows/release.yml contains a dangerous GitHub Actions workflow pattern.
Path: .github/workflows/release.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Other fixtures cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;agent control-plane drift&lt;/li&gt;
&lt;li&gt;out-of-scope agent edits&lt;/li&gt;
&lt;li&gt;missing test evidence&lt;/li&gt;
&lt;li&gt;MCP config drift&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Agent Gate is not
&lt;/h2&gt;

&lt;p&gt;Agent Gate is not a replacement for code review.&lt;/p&gt;

&lt;p&gt;It does not try to find every semantic bug.&lt;/p&gt;

&lt;p&gt;It does not know whether a function is logically correct.&lt;/p&gt;

&lt;p&gt;It does not prove that tests are sufficient.&lt;/p&gt;

&lt;p&gt;It does not replace a human reviewer, an LLM reviewer, or normal CI.&lt;/p&gt;

&lt;p&gt;It answers a narrower question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Did this PR cross deterministic policy boundaries before merge?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the problem I want it to solve well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current limitations
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;v0.1.2&lt;/code&gt; is still a prerelease.&lt;/p&gt;

&lt;p&gt;Known limitations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;APIs, rule names, reports, and config may change.&lt;/li&gt;
&lt;li&gt;CODEOWNERS and reviewer evidence are not implemented yet.&lt;/li&gt;
&lt;li&gt;Package and dependency drift rules are not implemented yet.&lt;/li&gt;
&lt;li&gt;GitHub Actions job-level permission escalation comparison is limited.&lt;/li&gt;
&lt;li&gt;Test evidence is file-pattern based and does not prove semantic coverage.&lt;/li&gt;
&lt;li&gt;PR comment upsert requires &lt;code&gt;issues: write&lt;/code&gt; and can warn on fork PRs with read-only tokens.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I want feedback on
&lt;/h2&gt;

&lt;p&gt;I am especially interested in feedback from people trying AI-generated PRs in real repositories.&lt;/p&gt;

&lt;p&gt;The main questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which findings should block by default?&lt;/li&gt;
&lt;li&gt;Which findings should stay warning-only?&lt;/li&gt;
&lt;li&gt;What high-risk path patterns do you use?&lt;/li&gt;
&lt;li&gt;Would CODEOWNERS or reviewer evidence make this more useful?&lt;/li&gt;
&lt;li&gt;Should package script and dependency drift be part of the gate?&lt;/li&gt;
&lt;li&gt;What would make this too noisy to adopt?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feedback issue:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/sjh9714/Agent-Gate/issues/27" rel="noopener noreferrer"&gt;https://github.com/sjh9714/Agent-Gate/issues/27&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/sjh9714/Agent-Gate" rel="noopener noreferrer"&gt;https://github.com/sjh9714/Agent-Gate&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing thought
&lt;/h2&gt;

&lt;p&gt;LLM reviewers are useful.&lt;/p&gt;

&lt;p&gt;But if AI-generated PRs become part of normal engineering workflows, teams will also need deterministic gates.&lt;/p&gt;

&lt;p&gt;Not every review question should be probabilistic.&lt;/p&gt;

&lt;p&gt;Some questions are simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Did this PR stay within scope?&lt;br&gt;&lt;br&gt;
Did workflow permissions escalate?&lt;br&gt;&lt;br&gt;
Did agent control-plane files change?&lt;br&gt;&lt;br&gt;
Is there matching test evidence?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the space Agent Gate is trying to explore.&lt;/p&gt;

&lt;p&gt;Use your LLM reviewer for judgment.&lt;/p&gt;

&lt;p&gt;Use Agent Gate for deterministic merge evidence.&lt;/p&gt;

&lt;p&gt;Disclosure: I used AI assistance to help draft and edit this article, and I reviewed the technical claims before publishing.&lt;/p&gt;

</description>
      <category>devtools</category>
      <category>security</category>
      <category>ai</category>
      <category>github</category>
    </item>
    <item>
      <title>Auditing GitHub CLI extensions before installing more</title>
      <dc:creator>JinHyuk Sung</dc:creator>
      <pubDate>Thu, 11 Jun 2026 09:50:21 +0000</pubDate>
      <link>https://dev.to/sjh9714/auditing-github-cli-extensions-before-installing-more-f2d</link>
      <guid>https://dev.to/sjh9714/auditing-github-cli-extensions-before-installing-more-f2d</guid>
      <description>&lt;p&gt;GitHub CLI extensions are useful, but extension discovery has a small practical problem: it is easy to find &lt;em&gt;more&lt;/em&gt; extensions before you understand whether your current setup already covers the workflows you care about.&lt;/p&gt;

&lt;p&gt;I built a small browser-only audit page for that problem:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://sjh9714.github.io/gh-extension-atlas/audit.html?demo=1" rel="noopener noreferrer"&gt;https://sjh9714.github.io/gh-extension-atlas/audit.html?demo=1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It opens with a sample result loaded. If you want to check your own setup, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh extension list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then paste the output into the page.&lt;/p&gt;

&lt;p&gt;The audit runs locally in the browser. There is no sign-in, no analytics script, and no remote audit API. The pasted extension list is not uploaded.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the audit checks
&lt;/h2&gt;

&lt;p&gt;The page compares installed GitHub CLI extensions against the GitHub CLI Extension Atlas catalog:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/sjh9714/gh-extension-atlas" rel="noopener noreferrer"&gt;https://github.com/sjh9714/gh-extension-atlas&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;installed extensions that are already reviewed in the atlas&lt;/li&gt;
&lt;li&gt;installed extensions that are not listed yet&lt;/li&gt;
&lt;li&gt;missing Top Picks&lt;/li&gt;
&lt;li&gt;workflow coverage gaps&lt;/li&gt;
&lt;li&gt;copyable install commands for missing workflow recommendations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to install every recommended extension. The goal is to make the next install decision smaller and easier to review.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just use &lt;code&gt;gh extension search&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;gh extension search&lt;/code&gt; is useful when you already know what you are looking for.&lt;/p&gt;

&lt;p&gt;It is less useful when the question is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which terminal dashboard should I try first?&lt;/li&gt;
&lt;li&gt;Do I need a notification tool if I already use a broader dashboard?&lt;/li&gt;
&lt;li&gt;Which extension is for GitHub Actions operations versus workflow statistics?&lt;/li&gt;
&lt;li&gt;Is this branch cleanup tool the right fit for my risk tolerance?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are comparison questions, not search questions.&lt;/p&gt;

&lt;p&gt;The atlas tries to answer them with a reviewed catalog, Top Picks, comparison guides, and workflow recommendations.&lt;/p&gt;

&lt;h2&gt;
  
  
  A few examples
&lt;/h2&gt;

&lt;p&gt;For daily GitHub triage, the atlas points to &lt;code&gt;gh-dash&lt;/code&gt; first because it covers PRs, issues, and notifications in one terminal dashboard.&lt;/p&gt;

&lt;p&gt;For GitHub Actions, it separates different jobs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;gh-enhance&lt;/code&gt; for an interactive Actions TUI&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gh-workflow-stats&lt;/code&gt; for success rate and duration summaries&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gh-act&lt;/code&gt; for local workflow runs&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gh-actions-importer&lt;/code&gt; for migration work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For branch cleanup, it compares tools like &lt;code&gt;gh-poi&lt;/code&gt;, &lt;code&gt;gh-branch&lt;/code&gt;, &lt;code&gt;gh-clean-branches&lt;/code&gt;, &lt;code&gt;gh-tidy&lt;/code&gt;, and &lt;code&gt;gh-worktree&lt;/code&gt; because they sound related but solve different habits and risk profiles.&lt;/p&gt;

&lt;h2&gt;
  
  
  The data contract
&lt;/h2&gt;

&lt;p&gt;The catalog is also available as JSON:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://sjh9714.github.io/gh-extension-atlas/api/extensions.json" rel="noopener noreferrer"&gt;https://sjh9714.github.io/gh-extension-atlas/api/extensions.json&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each entry includes fields such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;repository&lt;/li&gt;
&lt;li&gt;category&lt;/li&gt;
&lt;li&gt;install command&lt;/li&gt;
&lt;li&gt;best-fit use case&lt;/li&gt;
&lt;li&gt;avoid-if note&lt;/li&gt;
&lt;li&gt;license&lt;/li&gt;
&lt;li&gt;archived status&lt;/li&gt;
&lt;li&gt;maintenance status&lt;/li&gt;
&lt;li&gt;verification date&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That makes it usable by scripts, documentation tools, or coding agents that need current extension metadata instead of stale memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  What feedback would help
&lt;/h2&gt;

&lt;p&gt;I am mainly looking for factual corrections and missing-extension suggestions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;inaccurate descriptions&lt;/li&gt;
&lt;li&gt;wrong categories&lt;/li&gt;
&lt;li&gt;misleading maintenance labels&lt;/li&gt;
&lt;li&gt;better comparisons between overlapping tools&lt;/li&gt;
&lt;li&gt;useful GitHub CLI extensions that are missing from the catalog&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you maintain a GitHub CLI extension and the atlas describes it poorly, a short correction is enough.&lt;/p&gt;

&lt;p&gt;Note: I used AI assistance while organizing the launch plan and editing this post, but the project metadata, examples, and claims were reviewed before publishing.&lt;/p&gt;

</description>
      <category>terminal</category>
      <category>github</category>
      <category>cli</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
