<?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: Pin Tsai</title>
    <description>The latest articles on DEV Community by Pin Tsai (@agoopintsai).</description>
    <link>https://dev.to/agoopintsai</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%2F4210130%2F6988722d-5587-4659-96e5-43ccd545b36e.png</url>
      <title>DEV Community: Pin Tsai</title>
      <link>https://dev.to/agoopintsai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/agoopintsai"/>
    <language>en</language>
    <item>
      <title>AI drafts, humans sign, tools can only say no</title>
      <dc:creator>Pin Tsai</dc:creator>
      <pubDate>Tue, 27 Oct 2026 07:38:51 +0000</pubDate>
      <link>https://dev.to/agoopintsai/ai-drafts-humans-sign-tools-can-only-say-no-4e23</link>
      <guid>https://dev.to/agoopintsai/ai-drafts-humans-sign-tools-can-only-say-no-4e23</guid>
      <description>&lt;p&gt;Most of the code on our team is written by Claude Code now. Several product lines, one shared database, a small team. Output stopped being the bottleneck a while ago.&lt;/p&gt;

&lt;p&gt;Accountability didn't get cheaper, though. It got harder. More changes landed than anyone could read, and the person signing off was signing for things they had never really seen.&lt;/p&gt;

&lt;p&gt;This post is about the rules we ended up with, and the small Claude Code plugin that came out of them. I'm mostly writing it because I want people to poke holes in the reasoning.&lt;/p&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%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0j49nmcr96clojx0cdqi.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%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0j49nmcr96clojx0cdqi.png" alt="Three layers, one spine: a human at the top, an AI judge in the middle, AI hands at the bottom, all reading and writing a separate brain repo. Tools around the edge can only say no." width="799" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The first instinct was wrong
&lt;/h2&gt;

&lt;p&gt;When AI-written changes started worrying us, we did the obvious thing: we added more checks. Every AI step got a human gate.&lt;/p&gt;

&lt;p&gt;Two things happened:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The AI got slower and more hesitant with each layer.&lt;/li&gt;
&lt;li&gt;The humans couldn't keep up.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And when people can't keep up, something quiet happens. They start accepting verbal reports as verification. "It's handled" replaces "show me."&lt;/p&gt;

&lt;p&gt;Then we had a payment-related incident. Looking back at the two days before it, the pattern was plain: &lt;strong&gt;the decision had run ahead of the evidence, and the gate was a person who was already out of attention.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So the chain broke at the human. But the only one who can answer "should this exist at all?" and "where does it stop?" is also the human. The problem wasn't too many humans or too few. It was human attention spent in the wrong places.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four rules
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Humans only make the decisions that matter
&lt;/h3&gt;

&lt;p&gt;What to build. Approve the spec. Approve the code. Write down &lt;em&gt;why&lt;/em&gt;. That's the human's whole job. Everything else can be drafted by the AI.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The AI questions the human before it codes
&lt;/h3&gt;

&lt;p&gt;Before anything touches money, schema or a shared contract, the AI "grills" the plan. It lays the plan out as a decision tree and asks the human only the questions that belong to a human:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the need real? Who named it?&lt;/li&gt;
&lt;li&gt;What does it cost to &lt;em&gt;not&lt;/em&gt; do it?&lt;/li&gt;
&lt;li&gt;Where is the boundary?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Implementation-level questions it answers itself, and for each answer it says where it's most likely to be wrong. The human overturns what they disagree with and signs a one-page sheet. Nothing gets built before the signature.&lt;/p&gt;

&lt;p&gt;This flips the usual direction. Normally the human reviews the AI. Here the AI also reviews the human, at the one moment it's cheapest to be wrong: before any code exists.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Decisions live in a repo, not in people's heads
&lt;/h3&gt;

&lt;p&gt;Decisions used to live in chat threads, task cards and memory. Three months later nobody could say why something had been decided, only that it had.&lt;/p&gt;

&lt;p&gt;Now every signed plan, every override and its reason goes into a separate Git repo we call the &lt;strong&gt;brain&lt;/strong&gt;. Plain Markdown, dated, append-only. The AI reads it before asking anything, so the thicker it gets, the fewer questions climb up to a human.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Tools can refuse, never approve
&lt;/h3&gt;

&lt;p&gt;This is the one I care most about.&lt;/p&gt;

&lt;p&gt;Hooks, gates, CI and lint get veto power and &lt;em&gt;nothing else&lt;/em&gt;. They can block an edit in a red zone. They can refuse a workflow that forgot to pin a cheap model. They can fail a build. They can never say yes.&lt;/p&gt;

&lt;p&gt;That's what keeps the AI from quietly becoming the boss: &lt;strong&gt;the only way to get a "yes" is a human signature.&lt;/strong&gt;&lt;/p&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%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frwd4v5rlieu28eydh041.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%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frwd4v5rlieu28eydh041.png" alt="One change from request to shipped: the human says what they want and approves spec and code, the AI triages and asks the brain, and grey chips mark where gates, CI, hooks and lint can refuse." width="799" height="598"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Two lessons from building it
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A rule that can't physically be pressed isn't a rule.&lt;/strong&gt; We designed "the human approves the PR on GitHub," and halfway through realised the AI and the reviewer were using the same account. GitHub doesn't let you approve your own PR. The rule looked great on paper and was impossible in practice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rules in documents don't hold. Rules in tools do.&lt;/strong&gt; We had a written guideline about not fanning out to too many subagents on the expensive model. One afternoon a single session spawned sixty-five of them anyway, most on the most expensive model. The guideline moved into a hook that same week.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it looks like in practice
&lt;/h2&gt;

&lt;p&gt;I packaged this as a Claude Code plugin called Shipright. You mark "red zones" (defaults: &lt;code&gt;**/migrations/**&lt;/code&gt;, &lt;code&gt;**/payment/**&lt;/code&gt;, &lt;code&gt;**/billing/**&lt;/code&gt;). When Claude tries to edit one without a signed decision for the current branch, it gets this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Blocked: migrations/0001_example.py is a red zone (**/migrations/**).
No consensus doc covers branch feat/example.
Exits: run /shipright:grill, or /shipright:grill --override "&amp;lt;reason&amp;gt;" (recorded in the brain log).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every block says what was stopped, why, and how to get out. An override is allowed, but it's written down with a reason and a date.&lt;/p&gt;

&lt;p&gt;There's one subtlety. If the gate only checks "does a signed doc exist," the AI can just write the doc itself. So the gate has tiers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tier&lt;/th&gt;
&lt;th&gt;Gate opens when&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;file&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A decision doc for this branch exists in the brain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;commit&lt;/code&gt; (default)&lt;/td&gt;
&lt;td&gt;The doc is committed and clean in the brain repo, and optionally not committed by the AI's git identity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;github&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The spec PR is approved on GitHub (designed, not built yet)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In &lt;code&gt;commit&lt;/code&gt; tier the AI also can't run &lt;code&gt;git commit&lt;/code&gt; against the brain from Bash. A human has to.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it doesn't do (yet)
&lt;/h2&gt;

&lt;p&gt;I'd rather list these than have someone find them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It watches Edit, Write and NotebookEdit. A Bash &lt;code&gt;sed&lt;/code&gt; or &lt;code&gt;echo &amp;gt;&lt;/code&gt; into a red-zone file isn't caught.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cd brain &amp;amp;&amp;amp; git commit&lt;/code&gt; in a single Bash call slips past the commit check.&lt;/li&gt;
&lt;li&gt;Hooks fail &lt;em&gt;open&lt;/em&gt; on internal errors, on purpose. The only deliberate denies are a broken config and the gate itself.&lt;/li&gt;
&lt;li&gt;The "review twice" idea (spec PR, then code PR) is only enforced up to the commit layer today.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where I'd like your eyes
&lt;/h2&gt;

&lt;p&gt;These are the parts I'm least sure about:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Is "tools only veto" too strict?&lt;/strong&gt; Some teams auto-merge on green CI and seem fine. Is there a class of change where a tool saying yes is genuinely safe?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Does grilling scale?&lt;/strong&gt; It works for one human and a handful of risky changes a week. I don't know what happens with ten people.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Is a separate decision repo worth it&lt;/strong&gt;, versus ADRs inside each product repo? We chose separate because several products share contracts, but it's another thing to keep alive.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How would you close the Bash hole&lt;/strong&gt; without making the gate so noisy that people turn it off?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you've built something similar, or tried this and watched it fail, I'd really like to hear how.&lt;/p&gt;

&lt;p&gt;The plugin is open source (Apache-2.0): &lt;a href="https://github.com/agoopintsai/shipright" rel="noopener noreferrer"&gt;https://github.com/agoopintsai/shipright&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>codereview</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
