<?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: sagar jain</title>
    <description>The latest articles on DEV Community by sagar jain (@sagar_jain4010).</description>
    <link>https://dev.to/sagar_jain4010</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%2F3998494%2F2aecaf2a-509a-4e28-87ee-6d30bf83e417.png</url>
      <title>DEV Community: sagar jain</title>
      <link>https://dev.to/sagar_jain4010</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sagar_jain4010"/>
    <language>en</language>
    <item>
      <title>Do You Need a Model Abstraction Layer? Usually a Thin One</title>
      <dc:creator>sagar jain</dc:creator>
      <pubDate>Tue, 15 Sep 2026 08:00:21 +0000</pubDate>
      <link>https://dev.to/sagar_jain4010/do-you-need-a-model-abstraction-layer-usually-a-thin-one-ffg</link>
      <guid>https://dev.to/sagar_jain4010/do-you-need-a-model-abstraction-layer-usually-a-thin-one-ffg</guid>
      <description>&lt;p&gt;Yes, build one, and keep it thin. One internal function that takes a typed request, handles retries, timeouts, logging, and routing, and returns a typed response, with the provider SDK hidden behind an adapter. Don't build a general framework, and don't adopt a heavy one blindly. The leaky parts (tool-call formats, streaming shapes, structured-output modes, error codes) will leak through anything, and a thick abstraction means you spend more time fighting it than you would have spent switching providers.&lt;/p&gt;

&lt;h2&gt;
  
  
  What belongs in the thin layer
&lt;/h2&gt;

&lt;p&gt;Roughly three hundred lines you own outright: a typed request and response, two or three provider adapters, model aliases in config, the reliability layer, logging and cost accounting in one place, and flags for model and prompt version. Every item on that list is work you'd do with or without an abstraction.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A typed request (messages, tools, output schema, an alias for the model tier) and a typed response (content, tool calls, token usage, finish reason).&lt;/li&gt;
&lt;li&gt;Two or three provider adapters, each translating that request into the vendor's SDK call and back.&lt;/li&gt;
&lt;li&gt;Model aliases in config: &lt;code&gt;fast&lt;/code&gt;, &lt;code&gt;smart&lt;/code&gt;, &lt;code&gt;long-context&lt;/code&gt;, mapping to actual model ids per environment. Application code never mentions a vendor's model name.&lt;/li&gt;
&lt;li&gt;Timeouts, bounded retries with jitter, a circuit breaker, and an idle-stream watchdog.&lt;/li&gt;
&lt;li&gt;Feature flags for model and prompt version, so rollback is a config change.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What to leave out
&lt;/h2&gt;

&lt;p&gt;Prompt DSLs. Chain and graph orchestrators baked into the core. "Memory" modules with opinions about your database. Vendor-specific "agents" that hide their loop from you. Prompts stay as versioned files, and orchestration stays plain code on a queue you already run, with state in the database you already have.&lt;/p&gt;

&lt;p&gt;When a calling convention changes, and it changes a few times a year, a thin layer means editing one adapter. A framework means waiting for a release and then reading its changelog with your fingers crossed.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Thin layer you own&lt;/th&gt;
&lt;th&gt;Heavy framework&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Size&lt;/td&gt;
&lt;td&gt;~300 lines, all yours&lt;/td&gt;
&lt;td&gt;Thousands of lines, none yours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Breaking upstream change&lt;/td&gt;
&lt;td&gt;Edit one adapter&lt;/td&gt;
&lt;td&gt;Wait for a release, then adapt&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debugging a bad response&lt;/td&gt;
&lt;td&gt;Your own stack, top to bottom&lt;/td&gt;
&lt;td&gt;Nine frames of library code first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost to start&lt;/td&gt;
&lt;td&gt;About two days&lt;/td&gt;
&lt;td&gt;An afternoon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost to leave&lt;/td&gt;
&lt;td&gt;Nothing to leave&lt;/td&gt;
&lt;td&gt;A week, in our case&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I keep seeing teams reach for the framework because it feels like buying instead of building. In practice this is one of the places where the &lt;a href="https://www.shantiinfosoft.com/blog/build-vs-buy-automation-line-moved/" rel="noopener noreferrer"&gt;build-vs-buy line has moved&lt;/a&gt; toward building the small thing, precisely because the small thing is small.&lt;/p&gt;

&lt;h2&gt;
  
  
  When a heavier framework earns its place
&lt;/h2&gt;

&lt;p&gt;Four cases earn it: prototyping, where speed of trying ideas beats everything; teams that genuinely need many providers and many modalities on day one; teams without the capacity to maintain even three hundred lines; and regulated environments where a vendor's audited framework saves a compliance conversation. All four are legitimate, and all four still need guardrails.&lt;/p&gt;

&lt;p&gt;Pin the version. Wrap it behind your own interface so application code never imports it directly. Write one integration test per callback you depend on. Keep an ejection plan.&lt;/p&gt;

&lt;p&gt;Our own lesson: we adopted a popular orchestration framework early on one product. A minor version bump changed the semantics of a streaming callback, and partial responses started being treated as complete. It took most of a day to trace, because the stack was nine frames deep in library code before it reached anything we wrote. Ejecting took a week. Writing our own layer at the start would have taken two days, and we'd have understood every frame of every stack trace since.&lt;/p&gt;

&lt;h2&gt;
  
  
  The switching test
&lt;/h2&gt;

&lt;p&gt;The whole point of the layer fits into one test you can run in an afternoon, without touching application code. If it passes, your abstraction is doing its job. If switching means a branch, a refactor, a week of QA, and a nervous release, the abstraction has quietly become the thing you're locked into.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Change the model behind the &lt;code&gt;smart&lt;/code&gt; alias in config, in one file.&lt;/li&gt;
&lt;li&gt;Rerun the eval set against old and new.&lt;/li&gt;
&lt;li&gt;Compare pass rate, latency, and cost per call side by side.&lt;/li&gt;
&lt;li&gt;Decide, then roll forward or back with the same config change.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At &lt;a href="https://shantiinfosoft.com" rel="noopener noreferrer"&gt;Shanti Infosoft&lt;/a&gt; that thin client is shared across projects, and it has quietly outlived four generations of "must-have" frameworks, which tells you most of what I think about the trade. It's the default we start from on &lt;a href="https://www.shantiinfosoft.com/services/software-development-service/" rel="noopener noreferrer"&gt;custom software development&lt;/a&gt; work where a model sits somewhere in the stack.&lt;/p&gt;

&lt;p&gt;If your provider doubled prices tomorrow, how many files would you have to touch to move?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sagar Jain is the technical co-founder of Shanti Infosoft; his team of 80+ engineers works to a CMMI Level 5 standard and typically has a first working build in front of a client in about two weeks.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>ai</category>
      <category>backend</category>
      <category>programming</category>
    </item>
    <item>
      <title>Golden Datasets Rot: Keeping Your Eval Set Honest Over Time</title>
      <dc:creator>sagar jain</dc:creator>
      <pubDate>Sun, 13 Sep 2026 08:00:42 +0000</pubDate>
      <link>https://dev.to/sagar_jain4010/golden-datasets-rot-keeping-your-eval-set-honest-over-time-3994</link>
      <guid>https://dev.to/sagar_jain4010/golden-datasets-rot-keeping-your-eval-set-honest-over-time-3994</guid>
      <description>&lt;p&gt;An eval set is a snapshot of what your product needed the day you built it, and products, users, models, and even the golden answers themselves drift after that. So treat the set as a living asset: version it, feed it with real production failures every week, retire cases that no longer represent real traffic, and re-check the labels on a schedule. A 100 percent pass rate on a set nobody has touched in six months is a warning sign, whatever the dashboard says.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does an eval set rot?
&lt;/h2&gt;

&lt;p&gt;Quietly, and from several directions at once. Product policy changes while the golden answers still encode the old rule. A new user segment arrives asking unfamiliar questions. Eval cases leak into the prompt as few-shot examples. Some labels were wrong on day one. And the set gets easy, because every failure was fixed and no hard cases replaced them.&lt;/p&gt;

&lt;p&gt;A refund window moving from 14 days to 30 is enough to turn a dozen gold answers into confidently wrong ones. The dashboard rarely tells you which mode you're in:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rot mode&lt;/th&gt;
&lt;th&gt;What the dashboard shows&lt;/th&gt;
&lt;th&gt;What is actually happening&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Policy change&lt;/td&gt;
&lt;td&gt;Pass rate holds steady&lt;/td&gt;
&lt;td&gt;Gold answers encode a rule the product dropped&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;New user segment&lt;/td&gt;
&lt;td&gt;Pass rate holds steady&lt;/td&gt;
&lt;td&gt;The set no longer resembles real traffic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Few-shot leakage&lt;/td&gt;
&lt;td&gt;Pass rate climbs&lt;/td&gt;
&lt;td&gt;The prompt is graded on cases it memorized&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Labels wrong on day one&lt;/td&gt;
&lt;td&gt;Pass rate holds steady&lt;/td&gt;
&lt;td&gt;You're optimizing toward somebody's mistake&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Set gone too easy&lt;/td&gt;
&lt;td&gt;Pass rate near 100%&lt;/td&gt;
&lt;td&gt;Every hard case was fixed, none replaced&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We hit the leakage one ourselves. Pass rate sat at 98 percent for two months while user complaints climbed. Someone had lifted six of the "hard" eval cases into the system prompt as examples of good output. The eval was grading the prompt on its own homework.&lt;/p&gt;

&lt;h2&gt;
  
  
  Feeding it from production
&lt;/h2&gt;

&lt;p&gt;Every week, pull four buckets out of the logs and label twenty to thirty cases from them. Every case carries a source tag and a date. Ambiguous ones get two labellers, and disagreements get discussed rather than averaged. That's the whole maintenance habit, and it takes about an hour once somebody owns it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Schema-validation failures.&lt;/strong&gt; Anything the parser rejected outright.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thumbs-downs.&lt;/strong&gt; The user has already told you; believe them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Escalations&lt;/strong&gt;, either to the bigger model or to a human.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A plain random sample&lt;/strong&gt;, so the set doesn't become a museum of failures.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Keep a separate "hard set" of the cases that failed at least once in production. It stays small and it runs on every prompt change, which is how it catches the regressions the big set is too diluted to notice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retiring and re-labelling
&lt;/h2&gt;

&lt;p&gt;Once a quarter, re-label a random 10 percent of the set blind, without showing the stored gold answer. If agreement with the stored labels drops below roughly 90 percent, audit the whole slice that sample came from. Retire cases tied to removed features, and archive them instead of deleting.&lt;/p&gt;

&lt;p&gt;Features come back, and so do their bugs.&lt;/p&gt;

&lt;p&gt;Bake in a rule that a case cannot enter the set without a named labeller. "Generated by the model and looked fine" is how you end up with an eval set that agrees with the model by construction.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers I watch
&lt;/h2&gt;

&lt;p&gt;Four of them. Pass rate sliced by the date a case was added. A per-case flakiness score, from running each case three times, so you know which failures are noise. The labeller agreement rate from the quarterly re-label. And the age distribution of the whole set, which tells you at a glance whether anyone is still feeding it.&lt;/p&gt;

&lt;p&gt;The first one earns its keep fastest. If cases from the last month pass at 80 percent while cases from a year ago pass at 99, the product has drifted away from the old set and the old set is flattering you.&lt;/p&gt;

&lt;p&gt;This is also my favourite question to put to vendors selling "agents." Real ones can show you their eval set and how it changed over the last quarter, and it's one of the fastest ways to tell &lt;a href="https://www.shantiinfosoft.com/blog/agent-washing-real-vs-fake/" rel="noopener noreferrer"&gt;a real agent from agent-washing&lt;/a&gt;. At &lt;a href="https://shantiinfosoft.com" rel="noopener noreferrer"&gt;Shanti Infosoft&lt;/a&gt; the eval set is a deliverable with a version number, handed over alongside the code, because a client who inherits a model without its eval set inherits something they can't safely change. That handover closes every &lt;a href="https://www.shantiinfosoft.com/services/machine-learning-development-service/" rel="noopener noreferrer"&gt;machine learning engagement&lt;/a&gt; we take on.&lt;/p&gt;

&lt;p&gt;When was the last time a case in your eval set was re-labelled by a human who didn't see the original answer?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sagar Jain leads engineering as technical co-founder of Shanti Infosoft, a CMMI Level 5 team of 80+ engineers.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>testing</category>
      <category>machinelearning</category>
      <category>llm</category>
    </item>
    <item>
      <title>Hiding LLM Latency Without Lying to the User</title>
      <dc:creator>sagar jain</dc:creator>
      <pubDate>Fri, 11 Sep 2026 08:00:05 +0000</pubDate>
      <link>https://dev.to/sagar_jain4010/hiding-llm-latency-without-lying-to-the-user-18ii</link>
      <guid>https://dev.to/sagar_jain4010/hiding-llm-latency-without-lying-to-the-user-18ii</guid>
      <description>&lt;p&gt;You cannot make a six-second model call feel instant, but you can make it feel short and honest: get the first token on screen inside a second, do the predictable work before the user asks for it, arrange the answer so the useful part arrives first, and show progress that corresponds to something real. Fake spinners and a "thinking..." label with no end in sight teach users that the feature is slow and shifty. Both are fixable, and most of the fixes are product decisions rather than infrastructure work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where does the time actually go?
&lt;/h2&gt;

&lt;p&gt;Two numbers, measured separately. Time to first token is dominated by queueing at the provider and by prompt processing, which scales with input length. Total time is generation, output tokens multiplied by per-token speed, plus every tool call, and tool calls run one after another unless you deliberately make them run together.&lt;/p&gt;

&lt;p&gt;A system prompt of six thousand tokens plus a big retrieved context adds a noticeable delay before anything appears, and every one of those tokens costs money too.&lt;/p&gt;

&lt;p&gt;The most common surprise when we instrument a slow feature: the model was fine, and the time went to three retrieval calls done sequentially, or to a bloated prompt nobody had trimmed since the pilot.&lt;/p&gt;

&lt;h2&gt;
  
  
  What works
&lt;/h2&gt;

&lt;p&gt;Seven fixes, roughly in the order I'd apply them. Most are product and code decisions rather than infrastructure spend, which is why they're worth trying before anyone proposes a faster model or a dedicated endpoint. The first two usually account for the bulk of the improvement a user can feel.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Stream everything visible.&lt;/strong&gt; A first token inside a second changes how the whole wait feels, even when the total is unchanged.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallelize tool calls&lt;/strong&gt; that don't depend on each other. Three sequential 800-millisecond lookups become one 800-millisecond wait.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prefetch on intent.&lt;/strong&gt; If a user has typed a question and paused, start retrieval before they hit enter. Wrong guesses cost pennies; right guesses save seconds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Split the work by model.&lt;/strong&gt; A small, fast model produces the first visible piece (a title or a one-line summary) while the larger model produces the detail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Order the output.&lt;/strong&gt; Ask for the direct answer first and the reasoning after. The user reads the useful part while the rest streams.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trim the prompt.&lt;/strong&gt; Long system prompts are the cheapest latency fix nobody makes, because trimming feels risky. That's what the eval set is for.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cap output length&lt;/strong&gt; for tasks that don't need an essay.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What honest progress looks like
&lt;/h2&gt;

&lt;p&gt;Honest progress shows real steps in words a user recognizes, and each label changes only when that step completes. If a task will genuinely take thirty seconds, say thirty seconds and offer to notify the user instead. Always give them a way to cancel. A progress indicator that corresponds to nothing is worse than no indicator at all.&lt;/p&gt;

&lt;p&gt;"Searching your last 30 tickets," then "drafting reply." Those are labels a support agent can check against reality.&lt;/p&gt;

&lt;p&gt;We learned the dishonest version the hard way. Early on we added a progress bar that animated to about 90 percent and then sat there until the response arrived. Actual latency didn't change. User feedback got noticeably worse, because a bar stuck at 90 percent feels broken in a way that a plain "working on it, about 20 seconds" doesn't. We ripped it out within two weeks.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Loading state&lt;/th&gt;
&lt;th&gt;What the user infers&lt;/th&gt;
&lt;th&gt;Whether it survived&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bar animating to 90%, then stalling&lt;/td&gt;
&lt;td&gt;"This thing is broken"&lt;/td&gt;
&lt;td&gt;Removed after two weeks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bare spinner with no end in sight&lt;/td&gt;
&lt;td&gt;"This is always slow"&lt;/td&gt;
&lt;td&gt;Replaced with named steps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Named steps that advance on completion&lt;/td&gt;
&lt;td&gt;"It's working through my request"&lt;/td&gt;
&lt;td&gt;Current default&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"About 20 seconds, want a ping?"&lt;/td&gt;
&lt;td&gt;"Fine, I'll do something else"&lt;/td&gt;
&lt;td&gt;Used for anything over ~15s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;Buyers judge AI features by feel, in the first minute of a demo and the first week of use. Slow and vague loses to fast and honest even when the slow one is more accurate, because latency is the one quality signal a buyer can read without doing the evaluation work themselves.&lt;/p&gt;

&lt;p&gt;Anyone who has watched &lt;a href="https://www.shantiinfosoft.com/blog/how-buyers-shop-for-ai-agents-2026/" rel="noopener noreferrer"&gt;how buyers evaluate AI agents&lt;/a&gt; knows that latency reads as competence. At &lt;a href="https://shantiinfosoft.com" rel="noopener noreferrer"&gt;Shanti Infosoft&lt;/a&gt; we now put a time-to-first-token budget in the acceptance criteria for any user-facing AI feature, alongside the accuracy target, because one without the other doesn't ship. It goes into the scope on every &lt;a href="https://www.shantiinfosoft.com/services/generative-ai-development-service/" rel="noopener noreferrer"&gt;generative AI build&lt;/a&gt; we take on.&lt;/p&gt;

&lt;p&gt;What does your loading state tell the user right now, and is any of it true?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sagar Jain is technical co-founder of Shanti Infosoft, a CMMI Level 5 company that has built software for 700+ businesses.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>performance</category>
      <category>ai</category>
      <category>webdev</category>
      <category>ux</category>
    </item>
    <item>
      <title>Least Privilege for AI Agents: Scope the Tools and the Tokens</title>
      <dc:creator>sagar jain</dc:creator>
      <pubDate>Wed, 09 Sep 2026 09:00:10 +0000</pubDate>
      <link>https://dev.to/sagar_jain4010/least-privilege-for-ai-agents-scope-the-tools-and-the-tokens-37ih</link>
      <guid>https://dev.to/sagar_jain4010/least-privilege-for-ai-agents-scope-the-tools-and-the-tokens-37ih</guid>
      <description>&lt;p&gt;An agent should get the narrowest tools and the shortest-lived tokens that let it do the one job in front of it. The same goes for data: only the slice that job needs. Most agent security incidents I've looked at came down to an agent holding an admin key it never needed, so an ordinary mistake turned into a data leak. Prompt injection makes the headlines, but sloppy scoping causes most of the damage I've seen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do agents end up with god-mode credentials?
&lt;/h2&gt;

&lt;p&gt;Convenience, and the pilot. The developer building the demo used their own token or an existing service account, and it had access to everything because that's what made the demo work on Friday. The demo became the product, and "we'll tighten permissions later" turned into a ticket that lost to features every sprint.&lt;/p&gt;

&lt;p&gt;This is the same dynamic that produces &lt;a href="https://www.shantiinfosoft.com/blog/vibe-coding-security-bill/" rel="noopener noreferrer"&gt;the security bill that comes due after vibe coding&lt;/a&gt;: speed borrowed against a bill nobody scheduled.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scope the tools
&lt;/h2&gt;

&lt;p&gt;Scoping tools means one tool per action, each with the smallest surface that action needs. No generic "run SQL." Reads and writes split into separate tools with separate permissions. Arguments validated in your own code before execution. Minimal fields returned. The model chooses the tool; your code decides whether the parameters are acceptable.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Expose &lt;code&gt;get_order(order_id)&lt;/code&gt; and &lt;code&gt;list_orders(customer_id, limit)&lt;/code&gt; rather than a query endpoint.&lt;/li&gt;
&lt;li&gt;Split reads from writes, so a read-only agent literally cannot call a write.&lt;/li&gt;
&lt;li&gt;Allow-list tables and hosts, and enforce strict id formats, before anything runs.&lt;/li&gt;
&lt;li&gt;If the agent needs an order status, don't hand it the whole customer record.&lt;/li&gt;
&lt;li&gt;Give write tools a dry-run mode, and use it in evals and shadow phases.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Scope the tokens
&lt;/h2&gt;

&lt;p&gt;Each agent gets its own service identity, and each task gets a token minted for that task. A support agent reading one customer's orders gets a token bound to that tenant, scoped to &lt;code&gt;orders:read&lt;/code&gt;, with a ten-minute lifetime. If the agent is tricked, the blast radius is one customer's read-only order history for ten minutes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Shared admin service account&lt;/th&gt;
&lt;th&gt;Task-scoped token&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Scope&lt;/td&gt;
&lt;td&gt;Everything the account can reach&lt;/td&gt;
&lt;td&gt;One tenant, &lt;code&gt;orders:read&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lifetime&lt;/td&gt;
&lt;td&gt;Until somebody remembers to rotate it&lt;/td&gt;
&lt;td&gt;Ten minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blast radius if tricked&lt;/td&gt;
&lt;td&gt;Every tenant, read and write&lt;/td&gt;
&lt;td&gt;One customer's order history&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audit trail&lt;/td&gt;
&lt;td&gt;"the AI service" did it&lt;/td&gt;
&lt;td&gt;Named agent id, per call&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Secrets never go into the prompt or the context window. The model shouldn't be able to see a key, so it can't be talked into repeating one. Every tool call is logged with the agent id, so the audit trail reads like a person's, because it should.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scope the data
&lt;/h2&gt;

&lt;p&gt;Retrieval has to respect the same access rules as the human asking. If your RAG index was built by a crawler running as an admin, the agent will happily surface documents the user could never open, and it will do it with a citation attached, which makes the leak look authoritative.&lt;/p&gt;

&lt;p&gt;We caught exactly this in an internal pilot. A knowledge-base bot indexed a shared drive using a service account with broad read access, which included folders belonging to HR. During testing a colleague asked it, out of curiosity, what a particular role was paid, and it answered with a figure and a filename. It never left the pilot group, and it changed how we build every index since: document-level ACLs stored alongside the embeddings, filtered at query time by the caller's identity, with a re-sync whenever source permissions change. Row-level security in the vector store is mandatory if the source had it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The checklist we run before an agent touches production
&lt;/h2&gt;

&lt;p&gt;The review takes about an hour and covers tools, tokens, and the data behind retrieval. Nothing on it is exotic. It's a list of questions with named answers, and the value comes from writing those answers down somewhere a person outside the build team can read them.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;For each tool:&lt;/strong&gt; its narrowest scope, whether it reads or writes, what validates the arguments, and what a dry run looks like.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;For each token:&lt;/strong&gt; who mints it, what it's bound to, how long it lives, and where the call is logged.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;For the data:&lt;/strong&gt; whose permissions retrieval inherits, and how we know those permissions are current.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's the best hour in the whole build. At &lt;a href="https://shantiinfosoft.com" rel="noopener noreferrer"&gt;Shanti Infosoft&lt;/a&gt; this review is a hard gate; the agent doesn't get a production identity until someone outside the build team has signed it off. It runs on every agent we deliver through our &lt;a href="https://www.shantiinfosoft.com/services/ai-development-company/" rel="noopener noreferrer"&gt;AI development work&lt;/a&gt;, including the ones a client will operate themselves afterwards.&lt;/p&gt;

&lt;p&gt;If your agent were tricked into doing the worst thing its current permissions allow, what exactly would happen?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sagar Jain is the technical co-founder of Shanti Infosoft, where agent systems ship under the same CMMI Level 5 process as everything else the team delivers.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>devops</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Least Privilege for AI Agents: Scope the Tools and the Tokens</title>
      <dc:creator>sagar jain</dc:creator>
      <pubDate>Wed, 09 Sep 2026 08:01:09 +0000</pubDate>
      <link>https://dev.to/sagar_jain4010/least-privilege-for-ai-agents-scope-the-tools-and-the-tokens-1bfj</link>
      <guid>https://dev.to/sagar_jain4010/least-privilege-for-ai-agents-scope-the-tools-and-the-tokens-1bfj</guid>
      <description>&lt;p&gt;An agent should get the narrowest tools and the shortest-lived tokens that let it do the one job in front of it. The same goes for data: only the slice that job needs. Most agent security incidents I've looked at came down to an agent holding an admin key it never needed, so an ordinary mistake turned into a data leak. Prompt injection makes the headlines, but sloppy scoping causes most of the damage I've seen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do agents end up with god-mode credentials?
&lt;/h2&gt;

&lt;p&gt;Convenience, and the pilot. The developer building the demo used their own token or an existing service account, and it had access to everything because that's what made the demo work on Friday. The demo became the product, and "we'll tighten permissions later" turned into a ticket that lost to features every sprint.&lt;/p&gt;

&lt;p&gt;This is the same dynamic that produces &lt;a href="https://www.shantiinfosoft.com/blog/vibe-coding-security-bill/" rel="noopener noreferrer"&gt;the security bill that comes due after vibe coding&lt;/a&gt;: speed borrowed against a bill nobody scheduled.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scope the tools
&lt;/h2&gt;

&lt;p&gt;Scoping tools means one tool per action, each with the smallest surface that action needs. No generic "run SQL." Reads and writes split into separate tools with separate permissions. Arguments validated in your own code before execution. Minimal fields returned. The model chooses the tool; your code decides whether the parameters are acceptable.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Expose &lt;code&gt;get_order(order_id)&lt;/code&gt; and &lt;code&gt;list_orders(customer_id, limit)&lt;/code&gt; rather than a query endpoint.&lt;/li&gt;
&lt;li&gt;Split reads from writes, so a read-only agent literally cannot call a write.&lt;/li&gt;
&lt;li&gt;Allow-list tables and hosts, and enforce strict id formats, before anything runs.&lt;/li&gt;
&lt;li&gt;If the agent needs an order status, don't hand it the whole customer record.&lt;/li&gt;
&lt;li&gt;Give write tools a dry-run mode, and use it in evals and shadow phases.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Scope the tokens
&lt;/h2&gt;

&lt;p&gt;Each agent gets its own service identity, and each task gets a token minted for that task. A support agent reading one customer's orders gets a token bound to that tenant, scoped to &lt;code&gt;orders:read&lt;/code&gt;, with a ten-minute lifetime. If the agent is tricked, the blast radius is one customer's read-only order history for ten minutes.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Shared admin service account&lt;/th&gt;
&lt;th&gt;Task-scoped token&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Scope&lt;/td&gt;
&lt;td&gt;Everything the account can reach&lt;/td&gt;
&lt;td&gt;One tenant, &lt;code&gt;orders:read&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lifetime&lt;/td&gt;
&lt;td&gt;Until somebody remembers to rotate it&lt;/td&gt;
&lt;td&gt;Ten minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blast radius if tricked&lt;/td&gt;
&lt;td&gt;Every tenant, read and write&lt;/td&gt;
&lt;td&gt;One customer's order history&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audit trail&lt;/td&gt;
&lt;td&gt;"the AI service" did it&lt;/td&gt;
&lt;td&gt;Named agent id, per call&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Secrets never go into the prompt or the context window. The model shouldn't be able to see a key, so it can't be talked into repeating one. Every tool call is logged with the agent id, so the audit trail reads like a person's, because it should.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scope the data
&lt;/h2&gt;

&lt;p&gt;Retrieval has to respect the same access rules as the human asking. If your RAG index was built by a crawler running as an admin, the agent will happily surface documents the user could never open, and it will do it with a citation attached, which makes the leak look authoritative.&lt;/p&gt;

&lt;p&gt;We caught exactly this in an internal pilot. A knowledge-base bot indexed a shared drive using a service account with broad read access, which included folders belonging to HR. During testing a colleague asked it, out of curiosity, what a particular role was paid, and it answered with a figure and a filename. It never left the pilot group, and it changed how we build every index since: document-level ACLs stored alongside the embeddings, filtered at query time by the caller's identity, with a re-sync whenever source permissions change. Row-level security in the vector store is mandatory if the source had it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The checklist we run before an agent touches production
&lt;/h2&gt;

&lt;p&gt;The review takes about an hour and covers tools, tokens, and the data behind retrieval. Nothing on it is exotic. It's a list of questions with named answers, and the value comes from writing those answers down somewhere a person outside the build team can read them.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;For each tool:&lt;/strong&gt; its narrowest scope, whether it reads or writes, what validates the arguments, and what a dry run looks like.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;For each token:&lt;/strong&gt; who mints it, what it's bound to, how long it lives, and where the call is logged.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;For the data:&lt;/strong&gt; whose permissions retrieval inherits, and how we know those permissions are current.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's the best hour in the whole build. At &lt;a href="https://shantiinfosoft.com" rel="noopener noreferrer"&gt;Shanti Infosoft&lt;/a&gt; this review is a hard gate; the agent doesn't get a production identity until someone outside the build team has signed it off. It runs on every agent we deliver through our &lt;a href="https://www.shantiinfosoft.com/services/ai-development-company/" rel="noopener noreferrer"&gt;AI development work&lt;/a&gt;, including the ones a client will operate themselves afterwards.&lt;/p&gt;

&lt;p&gt;If your agent were tricked into doing the worst thing its current permissions allow, what exactly would happen?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sagar Jain is the technical co-founder of Shanti Infosoft, where agent systems ship under the same CMMI Level 5 process as everything else the team delivers.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>devops</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Putting a Number on Tech Debt So It Competes for Roadmap Time</title>
      <dc:creator>sagar jain</dc:creator>
      <pubDate>Mon, 07 Sep 2026 08:00:32 +0000</pubDate>
      <link>https://dev.to/sagar_jain4010/putting-a-number-on-tech-debt-so-it-competes-for-roadmap-time-4agp</link>
      <guid>https://dev.to/sagar_jain4010/putting-a-number-on-tech-debt-so-it-competes-for-roadmap-time-4agp</guid>
      <description>&lt;p&gt;Tech debt loses roadmap fights because it arrives as a feeling and features arrive as numbers. So we put a number on it: the hours per month the debt costs us right now, and the hours the fix would take. Then the debt item goes on the same list as the features and gets ranked by the same rule. Some debt loses that fight honestly, and that's fine. What isn't fine is debt losing because nobody bothered to price it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why "we have a lot of tech debt" never wins
&lt;/h2&gt;

&lt;p&gt;Because it's unfalsifiable, and it sounds like engineers wanting to rewrite things. Leadership hears a preference. The competing feature request arrives with a customer name attached and a revenue guess beside it. Given one claim with numbers and one without, the numbered claim wins every planning round, and it should.&lt;/p&gt;

&lt;p&gt;The pressure gets worse when the board is pushing for AI. I've written before about &lt;a href="https://www.shantiinfosoft.com/blog/ai-psychosis-in-the-c-suite/" rel="noopener noreferrer"&gt;boards mandating AI before there's a use-case&lt;/a&gt;, and the engineering version of that story is a team asked to bolt an AI feature onto a system whose deploy takes forty minutes and whose test suite is red half the time. The debt is now the thing blocking the mandate, and still nobody has priced it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we measure the interest
&lt;/h2&gt;

&lt;p&gt;We treat debt as a loan and measure its interest in engineer-hours per month across four buckets: recurring toil, incident time, friction, and blocked work. Each bucket is a count you can source from a calendar, a postmortem, or a CI dashboard, so the total is a number somebody else can check.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Recurring toil.&lt;/strong&gt; Manual steps × frequency. A twenty-minute manual database migration step done three times a week is four hours a month, every month, forever.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Incident time.&lt;/strong&gt; Hours spent on incidents where this debt was a cause or made recovery slower. Be honest, and use the last quarter's postmortems as the source.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Friction.&lt;/strong&gt; Build and deploy time multiplied by how often it happens, plus time-to-first-merged-PR for a new joiner. A flaky forty-minute CI run at thirty runs a day is twenty hours of engineers waiting, per day, even if half of them context-switch productively.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blocked work.&lt;/strong&gt; Features that can't ship until this is fixed. List them by name; don't estimate their value, just make the dependency visible.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A worked example from an internal system, the deploy pipeline:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Bucket&lt;/th&gt;
&lt;th&gt;Interest&lt;/th&gt;
&lt;th&gt;Where the number came from&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Recurring toil&lt;/td&gt;
&lt;td&gt;~8 hrs/month&lt;/td&gt;
&lt;td&gt;Manual migration step, three times a week&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Incident time&lt;/td&gt;
&lt;td&gt;~6 hrs/month&lt;/td&gt;
&lt;td&gt;Last quarter's postmortems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Friction&lt;/td&gt;
&lt;td&gt;~40 hrs/month&lt;/td&gt;
&lt;td&gt;Slow CI run × runs per day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blocked work&lt;/td&gt;
&lt;td&gt;2 features&lt;/td&gt;
&lt;td&gt;Named on the card, not valued&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~54 hrs/month&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fix estimated at 80 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Payback in about six weeks. Written that way it beat a mid-sized feature in the next planning round, and nobody had to argue about craftsmanship.&lt;/p&gt;

&lt;h2&gt;
  
  
  What goes on the roadmap card
&lt;/h2&gt;

&lt;p&gt;Write the debt item exactly like a feature card: the outcome in plain language, the cost to fix, the monthly interest, the risk of ignoring it, and an expiry date. The expiry is the part people skip. Some debt is fine forever, because the system it lives in is being retired or barely changes.&lt;/p&gt;

&lt;p&gt;For the deploy pipeline the outcome line read "deploys in five minutes, migrations automated," which a product manager can hold in their head without knowing what a migration is. Say on the card when a system is on its way out, and stop paying attention to its debt.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed once we did this
&lt;/h2&gt;

&lt;p&gt;Fewer requests to rewrite things, because a rewrite priced honestly rarely wins. The debt that did win was the unglamorous kind: pipelines, flaky tests, a manual step everyone had normalized, a config file only one person understood. Engineers stopped bringing "everything is bad" to planning and started bringing invoices, which product people can argue with.&lt;/p&gt;

&lt;p&gt;Working across many client codebases at &lt;a href="https://shantiinfosoft.com" rel="noopener noreferrer"&gt;Shanti Infosoft&lt;/a&gt;, the pattern is the same everywhere: the debt that hurts most is almost never the debt engineers complain about most. Pricing it is how you find out which is which, and it's the first exercise we run on a &lt;a href="https://www.shantiinfosoft.com/services/software-consulting/" rel="noopener noreferrer"&gt;software consulting engagement&lt;/a&gt; before anyone proposes a roadmap. If you want a second opinion on your own numbers, &lt;a href="https://calendar.app.google/VT1kAUUEfgADa5Rt7" rel="noopener noreferrer"&gt;book half an hour&lt;/a&gt; and bring last quarter's postmortems.&lt;/p&gt;

&lt;p&gt;What is the most expensive piece of tech debt on your system right now, in hours per month, and could you defend that number to your CFO?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sagar Jain co-founded Shanti Infosoft on the technical side. The firm runs a CMMI Level 5 delivery process across a team of 80+ engineers.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>engineering</category>
      <category>management</category>
      <category>architecture</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Ship AI Features Behind a Flag: Shadow Mode First, Then Canary</title>
      <dc:creator>sagar jain</dc:creator>
      <pubDate>Sat, 05 Sep 2026 08:00:20 +0000</pubDate>
      <link>https://dev.to/sagar_jain4010/ship-ai-features-behind-a-flag-shadow-mode-first-then-canary-15ek</link>
      <guid>https://dev.to/sagar_jain4010/ship-ai-features-behind-a-flag-shadow-mode-first-then-canary-15ek</guid>
      <description>&lt;p&gt;The safest way to ship an AI feature is to run it in shadow mode first (compute the output on real traffic, log it, show the user nothing), compare it against what the human or the old system did, then canary it to a small slice with a kill switch you have actually tested. Big-bang launches of a probabilistic feature mean your customers find the failure modes for you, in public.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does shadow mode tell you that staging can't?
&lt;/h2&gt;

&lt;p&gt;Shadow mode tells you the real input distribution, real latency under real concurrency, the true daily cost at production volume, and the agreement rate against whatever the feature replaces. Staging gives you none of those, because staging traffic is a sample you wrote yourself and production traffic is a sample nobody wrote.&lt;/p&gt;

&lt;p&gt;The agreement rate is where the work sits. If the model and the humans agree 91 percent of the time, the job is sorting the other 9 percent into "model wrong," "human wrong," "both defensible," and "input was garbage," which you can only do with production examples.&lt;/p&gt;

&lt;p&gt;Run it for one to two weeks, long enough to include a weekday peak and whatever monthly cycle your users have. On one project the shadow phase showed that a third of the daily cost came from a single automated client hammering the endpoint with near-duplicate requests. Nobody would have found that in staging, and a cache rule fixed it before launch.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you canary a probabilistic feature?
&lt;/h2&gt;

&lt;p&gt;Canary a probabilistic feature by slicing traffic on a stable key, never per request, then stepping the slice up in stages with guardrail metrics that roll back automatically. A user who sees the AI answer on Monday and the old flow on Tuesday will report both as bugs, so consistency per user matters more than the percentage.&lt;/p&gt;

&lt;p&gt;Slice by tenant or by a stable user hash, then walk it up:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;One percent&lt;/strong&gt;, held two or three days, watching guardrails more than product metrics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Five percent&lt;/strong&gt;, long enough to cover a full weekday cycle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Twenty-five percent&lt;/strong&gt;, where cost and latency problems stop being theoretical.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One hundred percent&lt;/strong&gt;, with the flag still in the code and still drilled.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Guardrail metrics with automatic rollback thresholds are what make the canary safe instead of merely small:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Schema-validation failure rate above a set ceiling.&lt;/li&gt;
&lt;li&gt;p95 latency above what the product accepts.&lt;/li&gt;
&lt;li&gt;Thumbs-down or complaint rate versus the control slice.&lt;/li&gt;
&lt;li&gt;Cost per day above the budget line.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any of them trips, the flag flips back without a human deciding at 3am. That's the entire point of automating the threshold.&lt;/p&gt;

&lt;h2&gt;
  
  
  The kill switch you have tested
&lt;/h2&gt;

&lt;p&gt;A tested kill switch is four flags: feature on/off, model version, prompt version, and force fallback. Rollback becomes a config flip that lands in seconds, with no deploy. Untested, it's a switch whose fallback path hasn't run since the AI path was added, which is a different thing entirely.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Flag&lt;/th&gt;
&lt;th&gt;What it rolls back&lt;/th&gt;
&lt;th&gt;What usually trips it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Feature on/off&lt;/td&gt;
&lt;td&gt;The whole AI path&lt;/td&gt;
&lt;td&gt;A guardrail breach or a live incident&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model version&lt;/td&gt;
&lt;td&gt;A bad model upgrade&lt;/td&gt;
&lt;td&gt;Accuracy or cost regression after a swap&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prompt version&lt;/td&gt;
&lt;td&gt;A bad prompt change&lt;/td&gt;
&lt;td&gt;Schema failures spiking after a release&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Force fallback&lt;/td&gt;
&lt;td&gt;Traffic to the old deterministic flow&lt;/td&gt;
&lt;td&gt;Provider outage or latency blowout&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Test the switch in production, on purpose, on a schedule. We do a monthly flag drill. The reason we do it monthly is a switch we once didn't drill: flipping it took the whole endpoint down, because the fallback code path had never been exercised since the AI path was added, and a dependency it needed had been removed in the meantime. The kill switch worked perfectly. It killed everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why does this matter more for AI than for an ordinary feature?
&lt;/h2&gt;

&lt;p&gt;Because trust in a probabilistic feature collapses on visible failures and rarely comes back. A deterministic bug gets fixed and forgiven. An AI feature that confidently gave twenty customers wrong answers on launch day gets switched off by the business, and that decision tends to outlast whatever the next version would have scored.&lt;/p&gt;

&lt;p&gt;The project then joins the long list of &lt;a href="https://www.shantiinfosoft.com/blog/ai-agent-projects-dead-by-2027/" rel="noopener noreferrer"&gt;AI agent projects expected to be dead by 2027&lt;/a&gt;. Shadow mode and a slow canary are how you find those twenty answers before customers do.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://shantiinfosoft.com" rel="noopener noreferrer"&gt;Shanti Infosoft&lt;/a&gt; no AI feature goes to 100 percent without a shadow phase and a drilled kill switch. The same discipline carries into &lt;a href="https://www.shantiinfosoft.com/services/ai-integration/" rel="noopener noreferrer"&gt;AI integration work&lt;/a&gt; inside someone else's existing product, where the blast radius isn't ours to clean up. Clients occasionally push back on the extra week. The ones who have shipped AI before never do.&lt;/p&gt;

&lt;p&gt;Have you flipped your kill switch in production since the day you built it?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sagar Jain is technical co-founder at Shanti Infosoft, a CMMI Level 5 shop that has shipped software for 700+ companies.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>ai</category>
      <category>testing</category>
      <category>deployment</category>
    </item>
    <item>
      <title>An Afternoon Data-Readiness Audit Before Any AI Build</title>
      <dc:creator>sagar jain</dc:creator>
      <pubDate>Thu, 03 Sep 2026 08:00:25 +0000</pubDate>
      <link>https://dev.to/sagar_jain4010/an-afternoon-data-readiness-audit-before-any-ai-build-3bif</link>
      <guid>https://dev.to/sagar_jain4010/an-afternoon-data-readiness-audit-before-any-ai-build-3bif</guid>
      <description>&lt;p&gt;Before scoping any AI feature, spend one afternoon answering six questions about the data it will run on: where it lives, who owns it, how fresh it is, whether ground truth exists, what's missing, and who is allowed to see it. Most of the "the model isn't good enough" failures I've seen were data-readiness failures discovered in month three instead of hour three. The audit is cheap. Skipping it is how projects die.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do AI builds stall on data?
&lt;/h2&gt;

&lt;p&gt;AI builds stall on data because the pilot ran on a clean export and production runs on the real system. Real systems carry conflicting definitions, status columns that changed meaning, scanned PDFs, and access rules nobody mapped. None of that shows up in a demo, and all of it shows up around week five.&lt;/p&gt;

&lt;p&gt;The real thing is fourteen tables with three different definitions of "customer," a status column that has meant four things over the years, PDFs that are scans, and a set of fields nobody outside finance is cleared to read.&lt;/p&gt;

&lt;p&gt;Regulated industries feel this hardest, which is a large part of why &lt;a href="https://www.shantiinfosoft.com/blog/why-ai-projects-die-faster-fintech-healthtech/" rel="noopener noreferrer"&gt;AI projects die faster in fintech and healthtech&lt;/a&gt;: the model was fine, and the data-access question was never asked out loud.&lt;/p&gt;

&lt;h2&gt;
  
  
  The six questions, and what a bad answer sounds like
&lt;/h2&gt;

&lt;p&gt;The six questions are location and access path, ownership, freshness needed versus actual, ground truth, gaps and dirt, and permissions. Each one has a green answer and a red one, and the red answers are specific enough that you can hear them coming in a scoping call.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Location and access path.&lt;/strong&gt; Good: a read replica or an API with a named owner. Bad: "someone runs an export monthly and emails it."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ownership.&lt;/strong&gt; A person, with a name, who can answer questions about the schema. "The vendor" or "the old team" means nobody.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Freshness, needed versus actual.&lt;/strong&gt; A daily batch is fine for a monthly report and useless for a support agent answering about an order placed an hour ago.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ground truth.&lt;/strong&gt; You should be able to show me two hundred examples of the right answer, produced by someone whose judgment you trust. If the answer is "we'll know it when we see it," you can't build an eval set, and you can't build the feature.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gaps and dirt.&lt;/strong&gt; Null rates, free-text fields that should be enums, IDs that don't join, dates stored as text. Ten minutes of &lt;code&gt;GROUP BY&lt;/code&gt; and &lt;code&gt;COUNT(*)&lt;/code&gt; reveals most of it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permissions.&lt;/strong&gt; PII, contract terms, per-tenant isolation, retention rules. If the AI feature will read something a junior employee couldn't, that's a design constraint from day one.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  A concrete example
&lt;/h2&gt;

&lt;p&gt;One project wanted a support-ticket classifier trained and evaluated on the existing "category" field. A two-hour audit found that 40 percent of tickets were tagged "Other," that twelve categories had been renamed twice, and that busy agents had been picking the first item in the dropdown. The ground truth was fiction.&lt;/p&gt;

&lt;p&gt;That afternoon saved us from three sprints of tuning a model against a label nobody believed. The first sprint became relabelling five hundred tickets with two reviewers each, and the classifier that followed had something honest to be measured against. The same trade shows up on every finding:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What the audit turns up&lt;/th&gt;
&lt;th&gt;Cost if you find it in hour three&lt;/th&gt;
&lt;th&gt;Cost if you find it in month three&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;No usable ground truth&lt;/td&gt;
&lt;td&gt;One sprint of relabelling&lt;/td&gt;
&lt;td&gt;Three sprints tuning against a label nobody believes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monthly emailed export, no API&lt;/td&gt;
&lt;td&gt;A scoping decision&lt;/td&gt;
&lt;td&gt;A rebuild of the ingest path&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PII the feature can't legally read&lt;/td&gt;
&lt;td&gt;A design constraint&lt;/td&gt;
&lt;td&gt;A launch held by legal review&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Schema owner left the company&lt;/td&gt;
&lt;td&gt;An hour finding a replacement&lt;/td&gt;
&lt;td&gt;Weeks reverse-engineering columns&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What to do with the answers
&lt;/h2&gt;

&lt;p&gt;Score each of the six questions green or red, amber only if you must. Every red item becomes sprint zero, before a model is touched, and the answers go into the scope document so the client and the team hold the same picture. Re-run all six at every phase.&lt;/p&gt;

&lt;p&gt;Data readiness decays. An owner leaves, a schema changes, a new source appears, a retention rule tightens.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://shantiinfosoft.com" rel="noopener noreferrer"&gt;Shanti Infosoft&lt;/a&gt; this audit is part of how we scope every AI engagement, and it's the single most common reason a quoted timeline changes before a contract is signed. It's also the first thing we run when a team brings us in for &lt;a href="https://www.shantiinfosoft.com/services/ai-consulting/" rel="noopener noreferrer"&gt;AI consulting on a stalled build&lt;/a&gt;, because the fix is usually upstream of the model. I'd rather have that conversation in the first week than the fifteenth. If you want a second pair of eyes on your six answers, &lt;a href="https://calendar.app.google/VT1kAUUEfgADa5Rt7" rel="noopener noreferrer"&gt;grab a slot&lt;/a&gt; and bring your schema.&lt;/p&gt;

&lt;p&gt;If I asked you tomorrow morning for two hundred examples of the right answer, how long would it take you to find them?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sagar Jain is the technical co-founder of Shanti Infosoft, a CMMI Level 5 firm whose 80+ engineers ship AI systems into production.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>data</category>
      <category>machinelearning</category>
      <category>architecture</category>
    </item>
    <item>
      <title>The Take-Home Test We Replaced With a Debugging Session</title>
      <dc:creator>sagar jain</dc:creator>
      <pubDate>Tue, 01 Sep 2026 09:00:12 +0000</pubDate>
      <link>https://dev.to/sagar_jain4010/the-take-home-test-we-replaced-with-a-debugging-session-dio</link>
      <guid>https://dev.to/sagar_jain4010/the-take-home-test-we-replaced-with-a-debugging-session-dio</guid>
      <description>&lt;p&gt;We stopped sending take-home coding tests. Coding tools turned them into a measure of who has the better subscription. In their place we run a sixty-minute live debugging session in a small, realistic codebase, with any AI tool the candidate wants, and we watch how they read errors and how they decide what to trust. It predicts how someone performs in month three far better than a polished take-home ever did.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the take-home stopped working
&lt;/h2&gt;

&lt;p&gt;The submissions got perfect and the conversations got worse. Clean code, full test coverage, a tidy README, sensible commit messages, and then a follow-up call where the candidate couldn't explain why a function existed. Meanwhile strong candidates were declining to spend six unpaid hours on a test, so we were filtering for free time rather than skill.&lt;/p&gt;

&lt;p&gt;There's a bigger reason too. The way engineers work has shifted; &lt;a href="https://www.shantiinfosoft.com/blog/coding-agents-fastest-growing-github-repos/" rel="noopener noreferrer"&gt;coding agents are the fastest-growing thing on GitHub&lt;/a&gt;, and the day job now involves supervising generated code as much as writing it. A take-home tests the writing. We needed something that tests the supervising.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What we wanted to know&lt;/th&gt;
&lt;th&gt;Take-home test&lt;/th&gt;
&lt;th&gt;Live debugging session&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Can they produce clean code&lt;/td&gt;
&lt;td&gt;Yes, or their tool can&lt;/td&gt;
&lt;td&gt;Not measured&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can they explain their own work&lt;/td&gt;
&lt;td&gt;Often not, on the follow-up call&lt;/td&gt;
&lt;td&gt;Watched live, out loud&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Do they verify a wrong suggestion&lt;/td&gt;
&lt;td&gt;Invisible to us&lt;/td&gt;
&lt;td&gt;The timezone bug tests it directly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost to the candidate&lt;/td&gt;
&lt;td&gt;Around six unpaid hours&lt;/td&gt;
&lt;td&gt;Sixty minutes, scheduled&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What the session looks like
&lt;/h2&gt;

&lt;p&gt;A small service, roughly a thousand lines: an HTTP API, a database, a background job on a queue, and a tiny admin page. It runs locally in a container in under a minute, and we seed four bugs of different kinds into it before the call starts.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A timezone bug that only shows up for users west of UTC.&lt;/li&gt;
&lt;li&gt;A race between the job and the API on the same row.&lt;/li&gt;
&lt;li&gt;An off-by-one in cursor pagination that drops the last record of every page.&lt;/li&gt;
&lt;li&gt;An error message that lies (it says "not found" when the real problem is a permission check).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The candidate gets the repo, a terminal, a browser, and a running database, and can use whatever assistant they normally use. We ask them to think out loud, and we say up front that fixing all four is not the goal. Most people fix two. Some fix one, and it's still a strong session.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the rubric scores
&lt;/h2&gt;

&lt;p&gt;The rubric has five rows, each scored one to three by two interviewers independently, and none of them counts bugs fixed. It scores how the candidate reads an error, whether they reproduce before fixing, whether they verify what the assistant suggests, how they pick between a quick patch and the right fix, and when they stop to ask.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reads the error and the surrounding code before prompting or searching.&lt;/li&gt;
&lt;li&gt;Reproduces the bug before trying to fix it.&lt;/li&gt;
&lt;li&gt;Verifies what the assistant suggests instead of pasting it. We specifically watch what happens when the tool proposes a plausible wrong fix for the timezone bug, which it usually does.&lt;/li&gt;
&lt;li&gt;Explains the trade-off of the fix and picks deliberately.&lt;/li&gt;
&lt;li&gt;Knows when to stop and ask a question instead of thrashing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two interviewers scoring independently, then comparing, cut most of the "I just liked them" bias we used to have.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed in who we hired
&lt;/h2&gt;

&lt;p&gt;We hired fewer framework-trivia specialists and more people who can operate a system they didn't write. Two surprises came out of it: some senior candidates struggled because they hadn't personally debugged anything in years, and some juniors who learned to code by prompting froze when the assistant's fix didn't work.&lt;/p&gt;

&lt;p&gt;Both were useful things to know before an offer, and neither would have surfaced in a take-home. Hiring steadily for a team of 80-plus engineers at &lt;a href="https://shantiinfosoft.com" rel="noopener noreferrer"&gt;Shanti Infosoft&lt;/a&gt; means we run this session a lot, and it keeps earning its slot. It costs us an hour of two engineers' time per candidate. It saves us the far larger cost of finding out in month two. We now run the same format when staffing an &lt;a href="https://www.shantiinfosoft.com/services/it-consulting/" rel="noopener noreferrer"&gt;IT consulting engagement&lt;/a&gt; where the client interviews our people too, and it survives that scrutiny better than a portfolio does.&lt;/p&gt;

&lt;p&gt;When did you last watch a candidate debug something live, with the tools they'd actually use on the job?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sagar Jain is the technical co-founder of Shanti Infosoft, a CMMI Level 5 firm, and sits in on more of these sessions than any other kind of interview.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>hiring</category>
      <category>ai</category>
      <category>management</category>
    </item>
    <item>
      <title>The Take-Home Test We Replaced With a Debugging Session</title>
      <dc:creator>sagar jain</dc:creator>
      <pubDate>Tue, 01 Sep 2026 08:01:11 +0000</pubDate>
      <link>https://dev.to/sagar_jain4010/the-take-home-test-we-replaced-with-a-debugging-session-4npg</link>
      <guid>https://dev.to/sagar_jain4010/the-take-home-test-we-replaced-with-a-debugging-session-4npg</guid>
      <description>&lt;p&gt;We stopped sending take-home coding tests. Coding tools turned them into a measure of who has the better subscription. In their place we run a sixty-minute live debugging session in a small, realistic codebase, with any AI tool the candidate wants, and we watch how they read errors and how they decide what to trust. It predicts how someone performs in month three far better than a polished take-home ever did.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the take-home stopped working
&lt;/h2&gt;

&lt;p&gt;The submissions got perfect and the conversations got worse. Clean code, full test coverage, a tidy README, sensible commit messages, and then a follow-up call where the candidate couldn't explain why a function existed. Meanwhile strong candidates were declining to spend six unpaid hours on a test, so we were filtering for free time rather than skill.&lt;/p&gt;

&lt;p&gt;There's a bigger reason too. The way engineers work has shifted; &lt;a href="https://www.shantiinfosoft.com/blog/coding-agents-fastest-growing-github-repos/" rel="noopener noreferrer"&gt;coding agents are the fastest-growing thing on GitHub&lt;/a&gt;, and the day job now involves supervising generated code as much as writing it. A take-home tests the writing. We needed something that tests the supervising.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What we wanted to know&lt;/th&gt;
&lt;th&gt;Take-home test&lt;/th&gt;
&lt;th&gt;Live debugging session&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Can they produce clean code&lt;/td&gt;
&lt;td&gt;Yes, or their tool can&lt;/td&gt;
&lt;td&gt;Not measured&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can they explain their own work&lt;/td&gt;
&lt;td&gt;Often not, on the follow-up call&lt;/td&gt;
&lt;td&gt;Watched live, out loud&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Do they verify a wrong suggestion&lt;/td&gt;
&lt;td&gt;Invisible to us&lt;/td&gt;
&lt;td&gt;The timezone bug tests it directly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost to the candidate&lt;/td&gt;
&lt;td&gt;Around six unpaid hours&lt;/td&gt;
&lt;td&gt;Sixty minutes, scheduled&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What the session looks like
&lt;/h2&gt;

&lt;p&gt;A small service, roughly a thousand lines: an HTTP API, a database, a background job on a queue, and a tiny admin page. It runs locally in a container in under a minute, and we seed four bugs of different kinds into it before the call starts.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A timezone bug that only shows up for users west of UTC.&lt;/li&gt;
&lt;li&gt;A race between the job and the API on the same row.&lt;/li&gt;
&lt;li&gt;An off-by-one in cursor pagination that drops the last record of every page.&lt;/li&gt;
&lt;li&gt;An error message that lies (it says "not found" when the real problem is a permission check).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The candidate gets the repo, a terminal, a browser, and a running database, and can use whatever assistant they normally use. We ask them to think out loud, and we say up front that fixing all four is not the goal. Most people fix two. Some fix one, and it's still a strong session.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the rubric scores
&lt;/h2&gt;

&lt;p&gt;The rubric has five rows, each scored one to three by two interviewers independently, and none of them counts bugs fixed. It scores how the candidate reads an error, whether they reproduce before fixing, whether they verify what the assistant suggests, how they pick between a quick patch and the right fix, and when they stop to ask.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reads the error and the surrounding code before prompting or searching.&lt;/li&gt;
&lt;li&gt;Reproduces the bug before trying to fix it.&lt;/li&gt;
&lt;li&gt;Verifies what the assistant suggests instead of pasting it. We specifically watch what happens when the tool proposes a plausible wrong fix for the timezone bug, which it usually does.&lt;/li&gt;
&lt;li&gt;Explains the trade-off of the fix and picks deliberately.&lt;/li&gt;
&lt;li&gt;Knows when to stop and ask a question instead of thrashing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two interviewers scoring independently, then comparing, cut most of the "I just liked them" bias we used to have.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed in who we hired
&lt;/h2&gt;

&lt;p&gt;We hired fewer framework-trivia specialists and more people who can operate a system they didn't write. Two surprises came out of it: some senior candidates struggled because they hadn't personally debugged anything in years, and some juniors who learned to code by prompting froze when the assistant's fix didn't work.&lt;/p&gt;

&lt;p&gt;Both were useful things to know before an offer, and neither would have surfaced in a take-home. Hiring steadily for a team of 80-plus engineers at &lt;a href="https://shantiinfosoft.com" rel="noopener noreferrer"&gt;Shanti Infosoft&lt;/a&gt; means we run this session a lot, and it keeps earning its slot. It costs us an hour of two engineers' time per candidate. It saves us the far larger cost of finding out in month two. We now run the same format when staffing an &lt;a href="https://www.shantiinfosoft.com/services/it-consulting/" rel="noopener noreferrer"&gt;IT consulting engagement&lt;/a&gt; where the client interviews our people too, and it survives that scrutiny better than a portfolio does.&lt;/p&gt;

&lt;p&gt;When did you last watch a candidate debug something live, with the tools they'd actually use on the job?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sagar Jain is the technical co-founder of Shanti Infosoft, a CMMI Level 5 firm, and sits in on more of these sessions than any other kind of interview.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>hiring</category>
      <category>ai</category>
      <category>management</category>
    </item>
    <item>
      <title>Reviewing AI-Written Pull Requests Without Burning Out Reviewers</title>
      <dc:creator>sagar jain</dc:creator>
      <pubDate>Sun, 30 Aug 2026 08:00:35 +0000</pubDate>
      <link>https://dev.to/sagar_jain4010/reviewing-ai-written-pull-requests-without-burning-out-reviewers-4fad</link>
      <guid>https://dev.to/sagar_jain4010/reviewing-ai-written-pull-requests-without-burning-out-reviewers-4fad</guid>
      <description>&lt;p&gt;When AI writes most of the diff, code review becomes the bottleneck, and the fix is a review process built for volume rather than reviewers who read faster. Smaller PRs enforced by tooling, a written intent block from the author, automated checks that clear the mechanical issues before a human looks, and a daily review budget per engineer. Reading faster doesn't scale. Reading less, and better, does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why does review load explode?
&lt;/h2&gt;

&lt;p&gt;Because generation capacity went up and review capacity did not. An engineer with a coding agent produces three or four times the diff volume they used to, while the number of hours a reviewer has in a day stayed exactly the same. The queue absorbs the difference until somebody starts skimming.&lt;/p&gt;

&lt;p&gt;Skimming an AI-written diff is worse than skimming a human one, because the code looks confident and idiomatic even when it's wrong. Fluent bugs. Those are the ones that reach production, and it's exactly why &lt;a href="https://www.shantiinfosoft.com/blog/ai-writes-4x-code-qa-layer/" rel="noopener noreferrer"&gt;more AI code needs a heavier QA layer&lt;/a&gt;, starting with review itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we require in every AI-assisted PR
&lt;/h2&gt;

&lt;p&gt;Every AI-assisted pull request carries four things before a reviewer opens it: an intent block, a verification checklist the author signs, a size under the cap, and tests in the same change. The author does more work up front so the reviewer does less, which is the whole trade.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An intent block at the top of the description: what this changes and why, then what it deliberately leaves out. Three short paragraphs at most.&lt;/li&gt;
&lt;li&gt;A verification checklist the author ticks honestly: ran it locally, added or updated tests, read every line of the diff, and can explain any file touched outside the ticket's scope. "The agent added a helper in a file I never opened" is a common finding and a red flag.&lt;/li&gt;
&lt;li&gt;A size cap. Ours is around 400 changed lines. Bigger than that, split it or stack it. The tooling rejects the PR, so it never becomes a negotiation.&lt;/li&gt;
&lt;li&gt;Tests in the same PR, and a note on what the tests don't cover.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of this is anti-AI. Use whatever tool you like to write the code. The PR is still your claim that it's correct.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which checks run before a human reads a line?
&lt;/h2&gt;

&lt;p&gt;Everything mechanical runs first: lint, type checks, the test suite, coverage delta, dependency diff, secret scanning, and a generated summary telling the reviewer where the risk sits ("touches auth middleware and two migrations"). By the time a person opens the PR, what's left is judgment: does this design hold up, and what happens when it fails.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Who runs it&lt;/th&gt;
&lt;th&gt;Blocks the merge?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lint, types, tests, coverage delta&lt;/td&gt;
&lt;td&gt;CI&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;400-line size cap&lt;/td&gt;
&lt;td&gt;The tooling, automatically&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI first-pass review&lt;/td&gt;
&lt;td&gt;A bot, before review is requested&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Does this design hold up&lt;/td&gt;
&lt;td&gt;A named human via CODEOWNERS&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That AI first-pass reviewer has one firm rule: its comments are suggestions the author resolves before requesting review, never blockers and never a substitute for the human. It's good at catching the missing null check and terrible at knowing whether the change should exist at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you protect reviewer time?
&lt;/h2&gt;

&lt;p&gt;Give review an explicit budget. Two hours a day per engineer, and after that the queue waits until tomorrow. Route risky paths through CODEOWNERS to the people who know them, let anyone review the rest, and track two numbers: time to first review, and the PR size distribution.&lt;/p&gt;

&lt;p&gt;If sizes creep up, the cap isn't being enforced. Our own failed experiment: for a while we tried "everyone reviews everything" to spread knowledge. Time to first review went past three days and people rubber-stamped to clear the queue. Knowledge didn't spread anyway, because skimming teaches nothing. Small PRs plus rotating ownership worked better on both counts.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://shantiinfosoft.com" rel="noopener noreferrer"&gt;Shanti Infosoft&lt;/a&gt; this is now the standard across our engineering teams, and it's the first process we rewrite when a &lt;a href="https://www.shantiinfosoft.com/services/software-consulting/" rel="noopener noreferrer"&gt;software consulting engagement&lt;/a&gt; starts with "our velocity went up and our defect rate went up with it." The interesting side effect is that PR quality from human-only authors went up too. The intent block and the size cap were always good practice; the volume forced us to enforce them.&lt;/p&gt;

&lt;p&gt;How long does a PR sit in your queue before someone reads it properly, and do you know that number or are you guessing?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sagar Jain is the technical co-founder of Shanti Infosoft, which has delivered software for 700+ companies and reviews a great deal of machine-written code every week.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>codereview</category>
      <category>ai</category>
      <category>productivity</category>
      <category>engineering</category>
    </item>
    <item>
      <title>The Boring Layer Around Every LLM Call: Timeouts and Retries</title>
      <dc:creator>sagar jain</dc:creator>
      <pubDate>Fri, 28 Aug 2026 09:00:56 +0000</pubDate>
      <link>https://dev.to/sagar_jain4010/the-boring-layer-around-every-llm-call-timeouts-and-retries-4ig9</link>
      <guid>https://dev.to/sagar_jain4010/the-boring-layer-around-every-llm-call-timeouts-and-retries-4ig9</guid>
      <description>&lt;p&gt;Every LLM call in production needs a timeout tuned to the expected output, a retry policy with a hard cap and jitter, an idempotency key on any side effect that follows it, and a circuit breaker for the day the provider is degraded. None of that is AI work. All of it decides whether your feature stays up on a bad afternoon, and it's the layer most AI codebases I inherit are missing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do LLM calls need different defaults from a normal HTTP call?
&lt;/h2&gt;

&lt;p&gt;Because the latency distribution has a long tail and every retry costs real money. A typical internal API answers in 50 milliseconds with a p99 near 300. An LLM call answers in about 2 seconds with a p99 of 25 or more, and a long generation can legitimately run past a minute.&lt;/p&gt;

&lt;p&gt;Copy your usual 10-second HTTP timeout onto that and you'll cancel healthy requests, retry them, pay twice, and hit your rate limit sooner. Our defaults, which we then tune per call site, start from the shape of the call:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Call shape&lt;/th&gt;
&lt;th&gt;Total timeout&lt;/th&gt;
&lt;th&gt;Idle between tokens&lt;/th&gt;
&lt;th&gt;Retries&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Short structured call&lt;/td&gt;
&lt;td&gt;30s&lt;/td&gt;
&lt;td&gt;15s&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Long generation&lt;/td&gt;
&lt;td&gt;90 to 120s&lt;/td&gt;
&lt;td&gt;15s&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Batch job item&lt;/td&gt;
&lt;td&gt;30s&lt;/td&gt;
&lt;td&gt;15s&lt;/td&gt;
&lt;td&gt;2, under a cost ceiling&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Connect timeout is 5 seconds everywhere. The idle timeout is the useful one, because we stream what we can and a stalled stream is a much earlier and cheaper signal than a total timeout.&lt;/p&gt;

&lt;h2&gt;
  
  
  How many retries, and on what?
&lt;/h2&gt;

&lt;p&gt;Two, at most. Retry on 429s, 5xx responses, connection errors, and timeouts. Use exponential backoff with jitter and honour &lt;code&gt;Retry-After&lt;/code&gt; when the provider sends it. Never retry a 400 or a schema-validation failure with the identical request; change something (feed the error back, shorten the input) or give up.&lt;/p&gt;

&lt;p&gt;The mistake that taught us the jitter part: a batch job that retried five times with fixed one-second gaps. During a provider incident, a queue of about four thousand items all failed together and all retried together, in lockstep, five times each. We turned a provider slowdown into a self-inflicted rate-limit ban that lasted longer than the original incident. Now every retry policy carries a cost budget too, a per-hour ceiling on retry spend, and the job stops rather than burning through it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Idempotency: the part people forget
&lt;/h2&gt;

&lt;p&gt;The LLM call itself is usually safe to repeat. What follows it often isn't: send the email, create the ticket, post the comment, charge the card. If your timeout fires after the provider actually finished, and you retry, the model answers twice and the side effect runs twice.&lt;/p&gt;

&lt;p&gt;The pattern is borrowed wholesale from payment processing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write the intent before you call the model, as a row with a unique key and status &lt;code&gt;pending&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Pass that key through as the idempotency key on the side effect itself.&lt;/li&gt;
&lt;li&gt;On any timeout, check whether the work already completed before you retry.&lt;/li&gt;
&lt;li&gt;Mark the row &lt;code&gt;done&lt;/code&gt; only once the side effect confirms it ran.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Circuit breakers and what "degraded" looks like
&lt;/h2&gt;

&lt;p&gt;A circuit breaker trips after a threshold of failures inside a window, and while it's open the system stops sending hopeful requests. We start with five failures in sixty seconds per model endpoint. Degraded means you fall back on purpose instead of queueing traffic that has nowhere useful to go.&lt;/p&gt;

&lt;p&gt;Fall back to a second provider behind the same interface, a smaller model, a cached answer from an earlier run, or an honest degraded mode ("we'll email you the summary in a few minutes"). Then close the breaker gradually with a trickle of test traffic.&lt;/p&gt;

&lt;p&gt;I keep coming back to this because the industry conversation is about which agents are real and which are slop, and I think a large share of &lt;a href="https://www.shantiinfosoft.com/blog/decade-of-agents-not-slop/" rel="noopener noreferrer"&gt;what separates agents that last from agents that are slop&lt;/a&gt; is this unglamorous layer. At &lt;a href="https://shantiinfosoft.com" rel="noopener noreferrer"&gt;Shanti Infosoft&lt;/a&gt; it lives in one shared client wrapper that every AI project imports, so nobody has to remember it and nobody can skip it. It's also the first file we write when a &lt;a href="https://www.shantiinfosoft.com/services/software-development-service/" rel="noopener noreferrer"&gt;software development team&lt;/a&gt; hands us an AI feature that works on their laptop. If your provider's p99 has ever ruined an afternoon, &lt;a href="https://calendar.app.google/VT1kAUUEfgADa5Rt7" rel="noopener noreferrer"&gt;a short call&lt;/a&gt; is a cheap way to compare notes.&lt;/p&gt;

&lt;p&gt;What does your feature do at 2am when the provider's p99 triples for an hour?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sagar Jain is the technical co-founder of Shanti Infosoft, where 80+ engineers write the boring layer around the interesting part.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>backend</category>
      <category>architecture</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
