<?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: Daniil Pokrovsky</title>
    <description>The latest articles on DEV Community by Daniil Pokrovsky (@danii1).</description>
    <link>https://dev.to/danii1</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%2F6416%2F087b814d-c7c7-447b-bf4b-a24029763c24.jpg</url>
      <title>DEV Community: Daniil Pokrovsky</title>
      <link>https://dev.to/danii1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/danii1"/>
    <language>en</language>
    <item>
      <title>Teaching an AI agent to say no: the feasibility gate</title>
      <dc:creator>Daniil Pokrovsky</dc:creator>
      <pubDate>Fri, 24 Jul 2026 04:06:03 +0000</pubDate>
      <link>https://dev.to/danii1/teaching-an-ai-agent-to-say-no-the-feasibility-gate-6fo</link>
      <guid>https://dev.to/danii1/teaching-an-ai-agent-to-say-no-the-feasibility-gate-6fo</guid>
      <description>&lt;p&gt;The most expensive thing a coding agent can do is confidently implement the wrong thing.&lt;/p&gt;

&lt;p&gt;I learned this the usual way, by pointing an agent at a ticket that said, in full: "Improve the onboarding flow." It ran for forty minutes, touched eleven files, and opened a PR that redesigned a form nobody had complained about. The diff was clean. The tests passed. It was also useless, because the ticket never said what "improve" meant, and the agent, being an agent, picked an interpretation and committed to it.&lt;/p&gt;

&lt;p&gt;The PR got closed, the branch got deleted, and I got to explain to myself why I had just paid API prices for work a human would have refused to start.&lt;/p&gt;

&lt;p&gt;A human engineer, handed that ticket, does something agents don't do by default: they push back. "Improve how? For whom? Is this the drop-off on step 2 or the confusing copy on step 4?" That pushback is real work. Half the value of a senior engineer is refusing to build until the question is answerable.&lt;/p&gt;

&lt;p&gt;So the biggest single fix I've found for unreliable ticket automation is not a better model or a longer prompt. It's an explicit step where the agent is structurally required to say "no, not yet."&lt;/p&gt;

&lt;h2&gt;
  
  
  What the gate looks like
&lt;/h2&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%2F9tivqu4slpqeyzq8icpp.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%2F9tivqu4slpqeyzq8icpp.png" alt="The feasibility gate: the ticket and a read-only view of the codebase feed a feasibility check, which either lets implementation proceed to a PR or posts open questions back to the ticket and stops" width="800" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before any code gets written, I run the agent once in read-only mode against the formatted ticket and the actual codebase. Its only job is to answer three questions in writing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Is the requirement clear enough that two reasonable engineers would build roughly the same thing?&lt;/li&gt;
&lt;li&gt;Does the change fit this codebase as it exists today, or does the ticket assume architecture that isn't there?&lt;/li&gt;
&lt;li&gt;What decisions would I have to invent to complete this, and who should actually make them?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The output is a short markdown file written before any implementation. If the assessment comes back "clear," the pipeline proceeds to implementation and a PR. If it comes back with open questions, it stops and posts them to the ticket as a comment, addressed to whoever wrote it.&lt;/p&gt;

&lt;p&gt;Two details matter more than they look.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The gate runs read-only.&lt;/strong&gt; The assessment pass has no permission to edit files. The reason is incentives, not distrust of the model. An agent that can edit files while assessing will start "just fixing" things to make the ticket feasible, and now your feasibility check has side effects. Most coding agents have a native mode for this (Claude Code's plan mode can't write); use it instead of trusting a prompt that says "please don't change anything."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The questions go back to the ticket, not to a log.&lt;/strong&gt; A feasibility report that lands in a file on the server is a feasibility report nobody reads. Posting "Before I can implement this, I need answers to: ..." as a tracker comment gets the author to answer, and over a few weeks it trains them. People start writing tickets that survive the gate on the first try, because getting bounced by a robot is mildly embarrassing in a way that getting bounced by a colleague isn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a good rejection reads like
&lt;/h2&gt;

&lt;p&gt;Here's a lightly edited assessment from my own backlog, for a ticket titled "Add rate limiting to the API":&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This task is not ready to implement. Open questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Which API? The repo exposes a public REST API (&lt;code&gt;src/api/&lt;/code&gt;) and an internal webhook receiver (&lt;code&gt;src/webhook-server.ts&lt;/code&gt;). Rate limiting the webhook receiver would break the GitHub integration's retry behavior.&lt;/li&gt;
&lt;li&gt;Per what? Per IP, per API key, and per account produce very different implementations. The codebase has no per-account request tracking today.&lt;/li&gt;
&lt;li&gt;What should a limited request receive? 429 with Retry-After is standard, but the mobile client (per &lt;code&gt;docs/clients.md&lt;/code&gt;) does not handle 429 and will surface a generic error.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Recommendation: split into "rate limit public REST per API key, 429 + Retry-After" and a separate client task.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Each question is grounded in something the agent found in the repo, not generic requirement-gathering theater. Question 3 is the kind of thing that becomes a production incident when an agent guesses. And the ticket author can answer all three in two minutes, so the ticket becomes implementable the same day.&lt;/p&gt;

&lt;p&gt;The grounding is the whole trick, honestly. "Please clarify the requirements" is noise. "You said rate limit the API, there are two APIs, here are their paths" is a colleague.&lt;/p&gt;

&lt;h2&gt;
  
  
  Failure modes I hit building this
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The gate that approves everything.&lt;/strong&gt; My first prompt asked "is this task feasible?" and the model, eager to please, said yes to almost anything. Reframing helped: instead of asking for a verdict, ask for the list of decisions the implementer would have to invent. If the list is empty, proceed. If it has entries, those entries are the rejection. Models are much better at enumerating ambiguity than at judging it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The gate that rejects everything.&lt;/strong&gt; Overcorrect and the agent starts demanding a spec for one-line copy changes. The calibration that worked for me: a question only counts as blocking if guessing wrong would produce a PR the reviewer rejects. "Which shade of gray" is not blocking. "Which of the two APIs" is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trusting the agent to stop on its own.&lt;/strong&gt; Sometimes the implementation run itself ends with the agent asking "Should I also migrate the old records? How would you like me to proceed?" and then the pipeline, seeing exit code 0, happily commits whatever half-state exists. I now scan the tail of the agent's output for decision-shaped questions ("which option," "should I," "your call") and treat a run that ends on them as a non-run: nothing gets committed, and the questions go to the ticket instead of into a PR. Committing past an unanswered question ships an answer nobody gave.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cost worries.&lt;/strong&gt; The gate is an extra model call, but a cheap one: read-only, no edit loop, a few minutes. Against one wasted forty-minute implementation run plus one wasted human review, it pays for itself the first time it fires. On my logs it stops roughly one ticket in five, exactly the tickets that used to produce the PRs I closed without merging.&lt;/p&gt;

&lt;h2&gt;
  
  
  The general lesson
&lt;/h2&gt;

&lt;p&gt;If you're wiring up ticket-to-code automation, in-house or otherwise: budget as much design effort for the refusal path as for the happy path. The happy path is a demo. The refusal path is what makes it survivable on a real backlog, where a meaningful fraction of tickets are one-line wishes written in a hurry between meetings.&lt;/p&gt;

&lt;p&gt;Agents can notice ambiguity fine. What they lack is a moment in the pipeline where noticing it is their entire job, and somewhere for the resulting questions to go. Give them both and everything downstream improves.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I ended up building
&lt;/h2&gt;

&lt;p&gt;This gate is built into &lt;a href="https://devintern.com" rel="noopener noreferrer"&gt;DevIntern&lt;/a&gt;, my tool that takes tickets from Jira, Linear, Trello, and four other trackers all the way to reviewed pull requests. Every run starts with this feasibility check; unclear tickets get their questions posted back as tracker comments instead of becoming PRs, and the assessment is saved as &lt;code&gt;feasibility-assessment.md&lt;/code&gt; alongside the run's other artifacts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;devintern PROJ-1842 &lt;span class="nt"&gt;--create-pr&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interactive use is free, no signup, and works with whichever coding agent you already use (Claude Code, Codex, Cursor, and others) on your own keys. Docs: &lt;a href="https://devintern.com/docs/code/quick-start/?utm_source=devto&amp;amp;utm_campaign=feasibility-gate" rel="noopener noreferrer"&gt;devintern.com/docs/code/quick-start&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>agile</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
