<?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: Aditya</title>
    <description>The latest articles on DEV Community by Aditya (@adityakumarpuri).</description>
    <link>https://dev.to/adityakumarpuri</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%2F3288446%2Ff341a095-af24-4414-a246-d378d766fc46.jpg</url>
      <title>DEV Community: Aditya</title>
      <link>https://dev.to/adityakumarpuri</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/adityakumarpuri"/>
    <language>en</language>
    <item>
      <title>While your build runs, walk</title>
      <dc:creator>Aditya</dc:creator>
      <pubDate>Sun, 11 Oct 2026 16:13:53 +0000</pubDate>
      <link>https://dev.to/adityakumarpuri/while-your-build-runs-walk-44cl</link>
      <guid>https://dev.to/adityakumarpuri/while-your-build-runs-walk-44cl</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week1-2026-10-05"&gt;Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;A GitHub Actions run already knows how long it is. You start it, and then you sit there, watching a bar that has already done the counting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://build-break.onrender.com/" rel="noopener noreferrer"&gt;Build Break&lt;/a&gt; takes that length and puts it on the phone. You paste a public repository, press start, and the screen becomes a clock that stays awake. You leave. If the street is worth keeping, you take one photo. When the run finishes, or when you decide you are done, a short journal entry is waiting.&lt;/p&gt;

&lt;p&gt;The first screen says the whole thing in one breath. While your build runs, walk. Snap what you see. An open model writes the entry when you get back.&lt;/p&gt;

&lt;p&gt;The screen is a glance. The walk is the rest of it.&lt;/p&gt;

&lt;p&gt;Paste &lt;code&gt;owner/repo&lt;/code&gt;, or a github.com URL, and the walk follows the newest run that is still going. The browser calls the public GitHub API from the phone, with no token. The countdown is the median of the last ten successful runs, minus the time already spent, and it never goes below zero. A repository with no successful history gets a fifteen-minute guess, and the page says so. "No recent successful runs, so this timer is a fifteen minute guess. The walk still ends when the run finishes." It checks that run every thirty seconds.&lt;/p&gt;

&lt;p&gt;If the guess runs out and the build is still going, the headline changes. "Go walk," becomes "Still out." Under it: the build has not finished.&lt;/p&gt;

&lt;p&gt;If nothing is in progress, the walk becomes a demo and one line says why. "No run in progress on that repo. This is a demo walk." A rate limit says "GitHub rate limit. This is a demo walk." A malformed URL stays on the start screen: "That does not look like a public GitHub repo." A repository GitHub cannot find stays an error too: "That repository is not public, or it does not exist." I would rather be told than be sent outside on a timer that was never real.&lt;/p&gt;

&lt;p&gt;Leave the field blank and it is a demo from the first step, anywhere from ten to sixty minutes. That is the walk in the pictures below. The end is the start plus those minutes, so a reload keeps counting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;It is live at &lt;a href="https://build-break.onrender.com/" rel="noopener noreferrer"&gt;build-break.onrender.com&lt;/a&gt;. Open it on a phone. On a desktop the same page sits in a narrow column, because this is a thing you carry.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu406jhnjyx4c5zfqeiss.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%2Fu406jhnjyx4c5zfqeiss.png" alt="Build Break on a phone. The line under the title says: while your build runs, walk." width="780" height="1688"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Press start with the field empty. The phone says go, and then a number. This one is 32:59, marked demo, with the screen kept awake.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq5f5ez5nyua9m3finou7.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%2Fq5f5ez5nyua9m3finou7.png" alt="The walk screen. Go walk, back in 32:59, demo. Capture, or end the walk." width="780" height="1688"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Capture is there if you want a picture. End walk is there if you come back early. In this demo there is no model key, so the note under the photo is written on the machine, one sentence from a small local set:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv8s8zsqf9ydt02lnofxn.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%2Fv8s8zsqf9ydt02lnofxn.png" alt="A stand of trees over pavement, and the note: the way ahead is quiet." width="780" height="1688"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The way ahead is quiet: pavement, trunks, and a pale sky.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That sentence is a stand-in. It lets you see the shape of a note before Gemma is pointed at a real street. It is not a record of a walk I took.&lt;/p&gt;

&lt;p&gt;When the demo clock hits zero, the journal writes the entry in the same voice. You can also end the walk yourself and get the entry then. This one is stamped 11 Oct 2026, 12:45 PM IST, one minute, demo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmpwzqk71x7afreaclktw.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%2Fmpwzqk71x7afreaclktw.png" alt="The journal. This week: 1 walk, 1 min outside while CI ran." width="780" height="1688"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I went out Sunday afternoon, 12:45 PM, and stayed for a minute. The way ahead is quiet: pavement, trunks, and a pale sky. It was a short loop, and a good one.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The line I keep looking at is the one above the entry. This week: one walk, one minute outside while CI ran.&lt;/p&gt;

&lt;p&gt;Point the app at Gemma and those stand-in sentences are replaced by whatever was actually in the photo, the weather if you allowed it, and how the run ended. On the laptop that model is Gemma 3 4B, because it can see. On Ollama Cloud it is Gemma 4 31B. The prompts stay the same.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0q9qp3xk9auuuq3mo0o6.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%2F0q9qp3xk9auuuq3mo0o6.png" alt="On a wide screen, Build Break stays a phone-width column in the middle of the black." width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;The license is MIT. The app is Next.js and TypeScript. Walks, notes, and the journal live in one SQLite file. Photos sit on disk next to it, under &lt;code&gt;DATA_DIR&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;GitHub is called from the browser. The model is one chat-completions client. The three screens are a start page, a walk, and a journal.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;The open piece is the model, and the model is one HTTP call.&lt;/p&gt;

&lt;p&gt;Build Break speaks the OpenAI chat completions API. Three environment variables aim it, and nothing else is hardcoded: &lt;code&gt;LLM_BASE_URL&lt;/code&gt;, &lt;code&gt;LLM_MODEL&lt;/code&gt;, and &lt;code&gt;LLM_API_KEY&lt;/code&gt;. With no key, you get the local stand-in in the screenshots above. &lt;code&gt;LLM_PROVIDER=mock&lt;/code&gt; keeps that path even when a key is sitting in the environment.&lt;/p&gt;

&lt;p&gt;For a real note I point it at Ollama on the laptop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;LLM_PROVIDER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ollama
&lt;span class="nv"&gt;LLM_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localhost:11434/v1
&lt;span class="nv"&gt;LLM_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gemma3:4b
&lt;span class="nv"&gt;LLM_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ollama
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key has to be non-empty, or the app assumes you have not chosen a model. Ollama ignores the value.&lt;/p&gt;

&lt;p&gt;The photo needs a model that can see. Gemma 3 at 270M and at 1B is text only, so those builds cannot read a picture. Gemma 3 4B can. It is asked for one short, warm sentence about what someone on a walk would notice: plants, animals, sky, the life of the street. No guessing past what is in the frame. The image is sent before the text, which is the order Gemma prefers.&lt;/p&gt;

&lt;p&gt;The same model writes the journal. Three to five sentences, first person, drawn from the time of day, the minutes outside, the notes, and the last few entries. A fact it was not given is left out. Weather appears only if you allowed location. A pattern gets a sentence only when a word actually shows up again. Plain, warm, no hashtags.&lt;/p&gt;

&lt;p&gt;Gemma 3, including the 4B, is released by Google under the &lt;a href="https://ai.google.dev/gemma/terms" rel="noopener noreferrer"&gt;Gemma Terms of Use&lt;/a&gt; (last modified 1 April 2026). The appendix on that page lists Gemma 3. It is Google's own license, with a prohibited-use policy. It is not the Apache License, and it is not an OSI open-source license. I use it because it can see a photo on a machine I already have, and that limit belongs in the post.&lt;/p&gt;

&lt;p&gt;When the laptop cannot hold the model, the same client talks to Ollama Cloud at &lt;code&gt;https://ollama.com/v1&lt;/code&gt;. The model id is &lt;code&gt;gemma4:31b&lt;/code&gt;, taken from Ollama's own list. The &lt;code&gt;:cloud&lt;/code&gt; alias is for a signed-in local Ollama, and it is the wrong string to send to the cloud API. Gemma 4 31B takes text and images and returns text, so one model still does both jobs. Gemma 4 is under the &lt;a href="https://ai.google.dev/gemma/apache_2" rel="noopener noreferrer"&gt;Apache License 2.0&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Changing the model is one line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;LLM_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gemma3:12b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Point &lt;code&gt;LLM_BASE_URL&lt;/code&gt; at another host and the prompts stay put.&lt;/p&gt;

&lt;p&gt;GitHub is called from the browser, so the request uses the phone's address. Unauthenticated calls are about sixty an hour. That is why a 403 becomes a demo walk with a sentence attached. Photos are resized in the browser to about 1024 pixels on the long edge, saved as JPEG, and only then uploaded to our own API. They are not sent to a model until an endpoint is configured. On localhost, that endpoint is Ollama on the same machine.&lt;/p&gt;

&lt;p&gt;The journal clock is the browser's time zone. That is why the demo stamp reads IST. The page asks for location once: add the weather from where you are. A no is remembered. Coordinates are not stored.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;The picture is of the street you are standing on. I wanted it read on the machine, with no account and no fee for each photo.&lt;/p&gt;

&lt;p&gt;Gemma 3 4B through local Ollama does that. If the sentence is too thin, I change &lt;code&gt;LLM_MODEL&lt;/code&gt;. The prompts stay. A closed vision API would have been a shorter afternoon, and then every walk would have been a metered call, with the photo leaving the phone for someone else's account. A walk every time a build starts is a bad match for a meter.&lt;/p&gt;

&lt;p&gt;Location is a choice for the same reason. Allow it, and the server asks &lt;a href="https://open-meteo.com/" rel="noopener noreferrer"&gt;Open-Meteo&lt;/a&gt; for the current conditions. There is no weather key. The sentence comes back in a fixed shape, like "28°C and clear." The latitude and longitude are not written into the journal. Refuse the prompt, and the entry never brings the weather up. Open-Meteo does see the coordinates when you allow them. A model provider does not receive the GPS. The database does not keep a record of where you were.&lt;/p&gt;

&lt;p&gt;Gemma 4 is there for the day the laptop is not enough. Because it is Apache 2.0, I can host it, or let Ollama Cloud host it, on the same three variables. The Render blueprint points the host at &lt;code&gt;gemma4:31b&lt;/code&gt; on Ollama Cloud, so the phone in your pocket does not have to be the computer that runs the weights.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Best Use of Gemma.&lt;/strong&gt; The one-line note and the journal entry are the model's work. On the laptop that is Gemma 3 4B, under the Gemma Terms of Use, because it can see. On Ollama Cloud it is Gemma 4 31B, under Apache 2.0. Either way the app is a thin timer around an open-weight model, and the model is one line to change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Use of Render.&lt;/strong&gt; Build Break is a Node server with a SQLite file and a folder of photos. That wants a disk that survives a restart. &lt;code&gt;render.yaml&lt;/code&gt; is the blueprint: the web service on the starter plan, &lt;code&gt;DATA_DIR&lt;/code&gt; at &lt;code&gt;/var/data&lt;/code&gt;, a 1 GB disk, and the model variables in the host environment. A persistent disk needs a paid instance. A free instance forgets the journal on restart. The app is live at &lt;a href="https://build-break.onrender.com/" rel="noopener noreferrer"&gt;build-break.onrender.com&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
    <item>
      <title>A code edit can pass the request and still drop something the prompt never said</title>
      <dc:creator>Aditya</dc:creator>
      <pubDate>Sun, 11 Oct 2026 12:23:15 +0000</pubDate>
      <link>https://dev.to/adityakumarpuri/a-code-edit-can-pass-the-request-and-still-drop-something-the-prompt-never-said-2a</link>
      <guid>https://dev.to/adityakumarpuri/a-code-edit-can-pass-the-request-and-still-drop-something-the-prompt-never-said-2a</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/kaggle-2026-09-23"&gt;Kaggle Benchmarking Challenge&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Benchmarked
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.kaggle.com/benchmarks/puriadityakumar/resolve" rel="noopener noreferrer"&gt;Resolve&lt;/a&gt; measures a small code change. I wanted a score for the failure I keep seeing: the edit does the thing that was asked, and drops a behavior the prompt never said again.&lt;/p&gt;

&lt;p&gt;Each item is one Python function and one requested edit. The model returns only the new function. The score is how many of 16 items are fully resolved, as a float from 0 to 1. A half-fix scores zero on that item.&lt;/p&gt;

&lt;p&gt;There are two tasks. &lt;strong&gt;resolve&lt;/strong&gt; checks the new behavior and the old behavior the prompt never restated. &lt;strong&gt;resolve-plus&lt;/strong&gt; adds an edge suite the prompt never showed. The two tasks are separate generations, so the second score can land above the first.&lt;/p&gt;

&lt;p&gt;The result this post is about: GPT-6.1 Sol and GPT-5.6 Luna are the only models at 0.9375 on both tasks. The task page rounds that to 0.94. Several other models match 0.9375 on resolve and then score lower on resolve-plus.&lt;/p&gt;

&lt;h3&gt;
  
  
  How it works
&lt;/h3&gt;

&lt;p&gt;The prompt shows the function, the one change, and two sample inputs. Anything the model writes besides the new function is thrown away. Hidden tests then run in two lists.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fail-to-pass&lt;/strong&gt; is the new behavior.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass-to-pass&lt;/strong&gt; is behavior the prompt never repeated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An item counts only when every test in both lists passes. A timeout, a crash, a missing function, or an empty suite is a failure. One failed test fails the item.&lt;/p&gt;

&lt;p&gt;resolve-plus uses the same rule and adds the edge suite. It is a new sample of the 16 items, not a second grade of the first sample.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdkgfln5gustipbq155e6.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%2Fdkgfln5gustipbq155e6.png" alt="Resolved means every hidden test passes. The prompt, the model, the hidden tests, and the score run in order. resolve checks both lists. resolve-plus adds an edge suite." width="800" height="1040"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Inspiration
&lt;/h3&gt;

&lt;p&gt;This is the rule &lt;a href="https://www.swebench.com/" rel="noopener noreferrer"&gt;SWE-bench&lt;/a&gt; uses for a resolved issue, scaled down to functions I wrote. The paper is Jimenez et al., &lt;a href="https://arxiv.org/abs/2310.06770" rel="noopener noreferrer"&gt;SWE-bench: Can Language Models Resolve Real-World GitHub Issues?&lt;/a&gt; (ICLR 2024).&lt;/p&gt;

&lt;p&gt;SWE-bench does not give credit because a patch compiles or because the new test passes. The issue is resolved only when the fail-to-pass tests and the pass-to-pass tests all pass. Resolve keeps that bar and drops the rest of the scaffolding: no scraped repository, no gold patch in the prompt, no tests written by the model. The failure worth reading is an edit that does the asked change and drops an invariant the prompt did not say again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Models Tested
&lt;/h2&gt;

&lt;p&gt;I started with one model from each of four families, then ran the Claude, GPT, and Gemini lines the proxy would serve, plus the open models listed below. Frontier and open models are charted separately so a single average cannot hide which group is carrying the score.&lt;/p&gt;

&lt;p&gt;Twenty-three models have both scores. A model is on a chart only when both have finished. Blue is resolve. Orange is resolve-plus. Charts are sorted by resolve-plus.&lt;/p&gt;

&lt;p&gt;Frontier: Claude Haiku 4.5, Haiku 5.5, Sonnet 5, Sonnet 5.5, Opus 5.5, GPT-5.4 mini, GPT-5.6 Luna, GPT-5.6 Sol, GPT-6.1 Sol, Gemini 3.5 Flash, Gemini 3.5 Flash-Lite, Gemini 3.6 Flash, Gemini 3.7 Flash, and Gemini 3.8 Flash.&lt;/p&gt;

&lt;p&gt;Open: Gemma 4 31B, Gemma 4 26B, gpt-oss 20B, gpt-oss 120B, DeepSeek-R1, GLM-5, Qwen 3 235B, Qwen 3 Coder 480B, and Qwen 3 Next 80B Instruct.&lt;/p&gt;

&lt;p&gt;Grok 4.5 and Grok 4.6 are in the Kaggle model list. The proxy returned model not found for both, so they are not on the charts. Qwen 3 Next 80B Thinking timed out three times on that same proxy, the last time after 3 of 16 items, so it is off the charts too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Findings
&lt;/h2&gt;

&lt;h3&gt;
  
  
  All 23 models
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgcs8cu7fm3286pns22dd.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%2Fgcs8cu7fm3286pns22dd.png" alt="All models. Blue is resolve, orange is resolve-plus. Sorted by resolve-plus." width="800" height="804"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GPT-6.1 Sol and GPT-5.6 Luna are tied at the top, 0.9375 on both tasks. That is 15 of 16 items, twice.&lt;/p&gt;

&lt;p&gt;The next group matches the 0.9375 resolve score and lands at 0.875 on resolve-plus: DeepSeek-R1, Claude Sonnet 5.5, and Claude Opus 5.5. Each of them resolved 15 items on the first task and 14 on the second.&lt;/p&gt;

&lt;p&gt;gpt-oss 20B is the bar that runs the other way, 0.75 then 0.875. The second task is a new sample, so a higher resolve-plus score is a different generation, not the edge suite helping. The floor of the combined chart is Qwen 3 235B and Gemma 4 26B, both at 0.6875 on resolve-plus.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frontier models
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwn0il3iktkni9bs5f61z.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%2Fwn0il3iktkni9bs5f61z.png" alt="Frontier models. Blue is resolve, orange is resolve-plus." width="800" height="527"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The frontier chart is the same tie at the top, then a clean step down.&lt;/p&gt;

&lt;p&gt;Opus 5.5 and Sonnet 5.5 both open at 0.9375 and close at 0.875. GPT-5.6 Sol opens at the same 0.9375 and closes at 0.8125, a two-item drop. Sonnet 5 holds 0.875 on resolve and falls to 0.75 on resolve-plus.&lt;/p&gt;

&lt;p&gt;Haiku 4.5 and Haiku 5.5 sit on the same pair, 0.875 and 0.875. On these 16 functions the newer small model did not move the score. Gemini 3.5 Flash and Gemini 3.6 Flash sit with them. Gemini 3.5 Flash-Lite is the frontier floor, 0.75 on both.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open models
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2490wfv9ek8a2pkek8i5.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%2F2490wfv9ek8a2pkek8i5.png" alt="Open models. Blue is resolve, orange is resolve-plus." width="799" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DeepSeek-R1 leads the open chart at 0.9375 and 0.875, level with Opus 5.5 and Sonnet 5.5 on the frontier chart. Gemma 4 31B is the only open model that holds 0.875 on both tasks. Gemma 4 26B is last, 0.75 then 0.6875.&lt;/p&gt;

&lt;p&gt;Qwen 3 Coder 480B, at 0.875 and 0.8125, beats the larger general Qwen 3 235B, at 0.8125 and 0.6875. gpt-oss 120B and Qwen 3 Next 80B Instruct are flat at 0.8125. gpt-oss 20B is the open-chart exception: its second sample scores 0.875 after a 0.75 first sample.&lt;/p&gt;

&lt;h3&gt;
  
  
  Score against list price
&lt;/h3&gt;

&lt;p&gt;The runs did not store tokens or a dollar bill, so this is not measured cost per item. The horizontal axis is the published output price per million tokens, taken from a &lt;a href="https://www.developersdigest.tech/blog/frontier-model-api-pricing-june-2026" rel="noopener noreferrer"&gt;rate card last updated 8 October 2026&lt;/a&gt;. That card reports the rates against the &lt;a href="https://www.anthropic.com/pricing" rel="noopener noreferrer"&gt;Anthropic&lt;/a&gt;, &lt;a href="https://openai.com/api/pricing" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt;, and &lt;a href="https://ai.google.dev/gemini-api/docs/pricing" rel="noopener noreferrer"&gt;Gemini&lt;/a&gt; pricing pages. Expensive is on the left. Cheap is on the right. A line connects models from the same provider. Open models are off this chart, and so are Gemini 3.6 Flash and Gemini 3.7 Flash, because that rate card does not list them. Haiku 5.5 is the under-100k rate. These prompts are one short function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzdrnehyqk4orhqhcua4k.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%2Fzdrnehyqk4orhqhcua4k.png" alt="resolve-plus against published output price. Expensive models are on the left, cheaper models on the right. GPT-5.6 Luna and GPT-6.1 Sol are tied at 0.9375, with Luna much cheaper." width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GPT-5.6 Luna is the efficient point: 0.9375 at $1.20 per million output tokens. GPT-6.1 Sol matches that score at $10. Claude Haiku 5.5 holds 0.875 at $0.50, the same score as Haiku 4.5 at $5 and Opus 5.5 at $20. Sonnet 5 and Sonnet 5.5 share the $10 output price. Sonnet 5.5 is the one at 0.875.&lt;/p&gt;

&lt;h3&gt;
  
  
  What a flat leaderboard hides
&lt;/h3&gt;

&lt;p&gt;The first pass was one model from each of four families: Claude Haiku 4.5, Gemma 4 31B, GPT-5.4 mini, and Gemini 3.7 Flash. Each resolved 14 of 16 items. The leaderboard looks flat until the second row. Haiku and Gemma stay at 0.875 on resolve-plus. GPT-5.4 mini and Gemini 3.7 Flash fall to 0.8125.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6adqf0lu95zl5ddf4lq7.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%2F6adqf0lu95zl5ddf4lq7.png" alt="resolve is 0.875 for every model. resolve-plus stays 0.875 for Claude Haiku 4.5 and Gemma 4 31B, and falls to 0.8125 for GPT-5.4 mini and Gemini 3.7 Flash." width="799" height="347"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Those two drops are different events.&lt;/p&gt;

&lt;p&gt;On &lt;code&gt;ring_push&lt;/code&gt;, each of those four models, on both tasks, made the requested change and failed a behavior the prompt never restated. Fail-to-pass passed. Pass-to-pass did not. A looser score would have counted those edits. This one does not. That miss was stable across those eight runs.&lt;/p&gt;

&lt;p&gt;GPT-5.4 mini’s lower resolve-plus score is the extra suite. On &lt;code&gt;truncate&lt;/code&gt;, the requested change and the old behavior both passed, and the edge suite failed. Haiku and Gemma did not lose an item that way.&lt;/p&gt;

&lt;p&gt;Gemini 3.7 Flash’s lower resolve-plus score is a different generation of the same items. &lt;code&gt;collapse_name&lt;/code&gt; passed the first time and failed the second. The extra suite was not what moved it.&lt;/p&gt;

&lt;p&gt;One number is hiding three things: an edit that breaks an unstated invariant, an edit that misses an edge the prompt never showed, and a second sample of the same item that comes out differently.&lt;/p&gt;

&lt;p&gt;One generation was enough to move &lt;code&gt;collapse_name&lt;/code&gt; from a pass to a fail. A one-shot score is a noisy picture of a model that is close to the line. The next run I would make is more than one sample per item.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Benchmark
&lt;/h2&gt;

&lt;p&gt;The public benchmark is &lt;a href="https://www.kaggle.com/benchmarks/puriadityakumar/resolve" rel="noopener noreferrer"&gt;Resolve on Kaggle&lt;/a&gt;. It is version 1, Apache 2.0, and marked public. The leaderboard on that page shows the first four models. The task pages list every run, including ones that did not finish. A model is in the charts here only when both scores finished.&lt;/p&gt;

&lt;p&gt;The two tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.kaggle.com/benchmarks/tasks/puriadityakumar/resolve/1" rel="noopener noreferrer"&gt;resolve&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.kaggle.com/benchmarks/tasks/puriadityakumar/resolve-plus/1" rel="noopener noreferrer"&gt;resolve-plus&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Suggested citation: Aditya Kumar Puri. Resolve. &lt;a href="https://www.kaggle.com/benchmarks/puriadityakumar/resolve/versions/1" rel="noopener noreferrer"&gt;https://www.kaggle.com/benchmarks/puriadityakumar/resolve/versions/1&lt;/a&gt;, 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Jimenez, Carlos E., John Yang, Alexander Wettig, Shunyu Yao, Kexin Pei, Ofir Press, and Karthik Narasimhan. “SWE-bench: Can Language Models Resolve Real-World GitHub Issues?” ICLR 2024. &lt;a href="https://arxiv.org/abs/2310.06770" rel="noopener noreferrer"&gt;https://arxiv.org/abs/2310.06770&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;SWE-bench. &lt;a href="https://www.swebench.com/" rel="noopener noreferrer"&gt;https://www.swebench.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Kaggle Community Benchmarks. &lt;a href="https://www.kaggle.com/benchmarks" rel="noopener noreferrer"&gt;https://www.kaggle.com/benchmarks&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;kaggle-benchmarks Python library. &lt;a href="https://github.com/Kaggle/kaggle-benchmarks" rel="noopener noreferrer"&gt;https://github.com/Kaggle/kaggle-benchmarks&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Google AI. “Introducing Community Benchmarks on Kaggle.” &lt;a href="https://dev.to/googleai/introducing-community-benchmarks-on-kaggle-35nc"&gt;https://dev.to/googleai/introducing-community-benchmarks-on-kaggle-35nc&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Frontier model API pricing, last updated 8 October 2026. &lt;a href="https://www.developersdigest.tech/blog/frontier-model-api-pricing-june-2026" rel="noopener noreferrer"&gt;https://www.developersdigest.tech/blog/frontier-model-api-pricing-june-2026&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Anthropic pricing. &lt;a href="https://www.anthropic.com/pricing" rel="noopener noreferrer"&gt;https://www.anthropic.com/pricing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OpenAI API pricing. &lt;a href="https://openai.com/api/pricing" rel="noopener noreferrer"&gt;https://openai.com/api/pricing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Gemini API pricing. &lt;a href="https://ai.google.dev/gemini-api/docs/pricing" rel="noopener noreferrer"&gt;https://ai.google.dev/gemini-api/docs/pricing&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>kagglechallenge</category>
      <category>ai</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>I built an agent that asks permission before it touches anything</title>
      <dc:creator>Aditya</dc:creator>
      <pubDate>Sun, 30 Aug 2026 18:25:43 +0000</pubDate>
      <link>https://dev.to/adityakumarpuri/i-built-an-agent-that-asks-permission-before-it-touches-anything-299c</link>
      <guid>https://dev.to/adityakumarpuri/i-built-an-agent-that-asks-permission-before-it-touches-anything-299c</guid>
      <description>&lt;p&gt;Every agent demo I watched this month had the same ending: the agent clicked "confirm" on itself. Nobody in the video batted an eye. The narrator called it "fully autonomous" and moved on.&lt;/p&gt;

&lt;p&gt;That's the part I can't get past. An agent that never stops isn't autonomous, it's just unattended.&lt;/p&gt;

&lt;p&gt;So for the WeMakeDevs × TrueFoundry Agent Harness Hackathon, I built Recap: a research-paper autopsy you can drive. You hand it a paper, it dissects it, and every time it wants to do something irreversible, it stops and waits for you. The agent supervises papers. You supervise the agent.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/puri-adityakumar/openwrite" rel="noopener noreferrer"&gt;https://github.com/puri-adityakumar/openwrite&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The job I gave it
&lt;/h2&gt;

&lt;p&gt;Research papers are a triage problem. You don't read one paper, you triage forty, and most of them don't deserve the forty minutes. The job I gave the agent: take an arXiv URL or a PDF, and come back with the parts a human actually needs. Not a summary. A workup.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp4mnvcrtec4nzkbrpl3a.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%2Fp4mnvcrtec4nzkbrpl3a.png" alt=" " width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;One click from landing to cockpit. The demo credentials sit right there because a tired judge is a real user segment.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What comes back is five surfaces: a live Trail of everything the agent did, a Coverage grid, a Claims↔Evidence table, an Authors tab, and a downloadable Audit. The Claims↔Evidence table is the one I'd want as a reviewer. Every claim in the paper, next to the evidence the agent found for it, and the gaps in between.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3fy3f9o7x4saxnox9s6u.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%2F3fy3f9o7x4saxnox9s6u.png" alt=" " width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The dashboard. First paint shows a populated run, not an empty state. Empty states are where demos go to die.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The pause is the product
&lt;/h2&gt;

&lt;p&gt;Here's the feature I actually care about: three approval gates. Verify, Publish, Save. Before the agent does anything irreversible, it pauses and asks. Not a toast you can ignore. A full stop.&lt;/p&gt;

&lt;p&gt;The Verify gate is deliberately obnoxious. Before the paper's untrusted code runs in a sandbox, you have to type the repo owner's name AND hold a button for three full seconds. That's not friction by accident. That's friction on purpose. Papers are not trusted code, and "run the repo this paper links to" deserves a speed bump.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0w0y5vz8bxxrm30wf8wt.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%2F0w0y5vz8bxxrm30wf8wt.png" alt=" " width="750" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Verify gate. Type the owner, hold for three seconds. If it feels excessive, try imagining what the code does.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Annoying answer: most agent safety demos are theater. A checkbox nobody reads is consent, not control. A pause you have to hold open is control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wiring it up
&lt;/h2&gt;

&lt;p&gt;The stack is boring on purpose: Next.js, Postgres, Redis, one &lt;code&gt;docker compose up&lt;/code&gt;, everything local. The interesting wiring is the agent harness.&lt;/p&gt;

&lt;p&gt;One command, no clone:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @truefoundry/trueforge@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives me a TrueForge server on localhost:8790. Then I registered GMI Cloud as the model provider, pointed at their Anthropic-compatible endpoint with a custom base_url, running MiniMax-M3. No adapter code. A curl with a manifest, done.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjm7p2neqjke781l5id1z.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%2Fjm7p2neqjke781l5id1z.png" alt=" " width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The cockpit mid-run. Real SSE events streaming in: turn created, deltas, tool calls. The Trail on the left is the agent's actual receipt.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;My app talks to TrueForge through its REST + SSE API. &lt;code&gt;lib/trueforge.ts&lt;/code&gt; ships an HttpTrueForgeClient, and the events come over the wire for real: &lt;code&gt;turn.created&lt;/code&gt;, &lt;code&gt;model.message.delta&lt;/code&gt;, &lt;code&gt;tool.approval_required&lt;/code&gt;, &lt;code&gt;turn.done&lt;/code&gt;. When a gate fires, my UI surfaces the pause, and your allow/deny decision routes back to TrueForge through its resume contract. Nothing in the hot path is mocked. There's a smoke script that proves the "pong" in the transcript came from the actual model.&lt;/p&gt;

&lt;h2&gt;
  
  
  What TrueForge took off my plate
&lt;/h2&gt;

&lt;p&gt;This is the list I'd have underestimated a week ago:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The agent runtime itself: turn lifecycle, retries, cancellation. I would have hand-rolled a state machine and shipped at least two race conditions.&lt;/li&gt;
&lt;li&gt;Event streaming. SSE with backpressure and reconnection is a project, not a file.&lt;/li&gt;
&lt;li&gt;Model-provider plumbing. Swapping GMI in without writing an adapter was the single best "oh, that's it?" moment of the hackathon.&lt;/li&gt;
&lt;li&gt;The approval-pause/resume contract. The hard part of human-in-the-loop isn't the UI, it's freezing a running turn and resuming it correctly after a human decides. That's a solved problem here, and I just used it.&lt;/li&gt;
&lt;li&gt;Sandbox handling, with a local fallback when no cloud sandbox is configured.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wrote the surfaces: gates, trail, audit, the cockpit UI. TrueForge ran the agent underneath them. That division of labor is the whole pitch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it broke
&lt;/h2&gt;

&lt;p&gt;The low point: the demo ran fine until tool execution. Daytona, the sandbox provider, kept refusing the write that publishes a sandbox snapshot. The docs made it sound like &lt;code&gt;write:sandboxes&lt;/code&gt; was enough. It isn't. You also need &lt;code&gt;write:snapshots&lt;/code&gt;, and nothing tells you that until the API returns a permission error mid-demo.&lt;/p&gt;

&lt;p&gt;The fix I reached for was TrueForge's local sandbox fallback, which auto-engages when no cloud sandbox provider is configured. The demo lived. And to be clear about the trade: tool execution behind the gate is skipped right now, and the harness says so honestly in the audit as &lt;code&gt;sandbox.disabled&lt;/code&gt;. It doesn't pretend. The audit shows the gap, which is exactly the behavior I built the whole product around.&lt;/p&gt;

&lt;p&gt;Honestly, that's the part I'm proudest of: the failure mode is visible, not hidden.&lt;/p&gt;

&lt;h2&gt;
  
  
  The review loop nobody asked about
&lt;/h2&gt;

&lt;p&gt;Quick one, because it shaped everything: every substantive change landed through a Qodo-reviewed pull request. Thirteen PRs, all reviewed. The approval-gates PR came back with 17 findings across two review passes, including a race condition in my event reducer and a missing TTL guard that could have double-approved a gate. Every finding triaged before merge. The loop became the norm: PR, review, fix, merge. 237 unit tests and 54 E2E tests green at the end of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The whole run
&lt;/h2&gt;

&lt;p&gt;If you'd rather watch than read:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/9iPQsysZ35k" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;em&gt;180 seconds, the whole run, no cuts.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fydj8dul1nf2z9r8m0tqj.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%2Fydj8dul1nf2z9r8m0tqj.png" alt=" " width="800" height="563"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The audit at the end. Every action logged, every decision attributed. If the agent did it, the audit can prove it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The agents are coming either way. The interesting question isn't whether they can do the work. It's whether you can see them doing it.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/puri-adityakumar/openwrite" rel="noopener noreferrer"&gt;https://github.com/puri-adityakumar/openwrite&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Biryani, With Love: A Deccan-Inspired Interactive Atlas</title>
      <dc:creator>Aditya</dc:creator>
      <pubDate>Sun, 02 Aug 2026 11:31:41 +0000</pubDate>
      <link>https://dev.to/adityakumarpuri/biryani-with-love-a-deccan-inspired-interactive-atlas-4amb</link>
      <guid>https://dev.to/adityakumarpuri/biryani-with-love-a-deccan-inspired-interactive-atlas-4amb</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/frontend-2026-07-29"&gt;Frontend Challenge - Comfort Food Edition, Perfect Landing&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Biryani, With Love&lt;/strong&gt; is an interactive editorial atlas about the many regional traditions that share the name biryani.&lt;/p&gt;

&lt;p&gt;I chose biryani because comfort food is rarely only about flavour. It can hold a city, a family ritual, a migration story, a celebration, and a memory of home in the same pot. The landing page follows that idea from Hyderabad through India and across the Indian Ocean.&lt;/p&gt;

&lt;p&gt;The experience includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A research-led map of eight Indian biryani traditions&lt;/li&gt;
&lt;li&gt;A method lab comparing kachchi, pakki, and one-pot cooking sequences&lt;/li&gt;
&lt;li&gt;A guided loop through fourteen traditions across nine countries&lt;/li&gt;
&lt;li&gt;A comparison tool for grain, method, flavour, heat, perfume, tang, and richness&lt;/li&gt;
&lt;li&gt;A historical route connecting language, court kitchens, regional grains, and Indian Ocean migration&lt;/li&gt;
&lt;li&gt;A research shelf that makes the supporting sources visible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The visual system is inspired by a contemporary Deccan pavilion. Saffron, peacock green, pomegranate red, plum, brass, and ivory create the palette. The hero uses CSS-built arches, minarets, jali panels, steam, rice grains, garnish, and an open copper handi.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/puri-adityakumar/embed/MYJZObG?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codepen.io/puri-adityakumar/pen/MYJZObG" rel="noopener noreferrer"&gt;Open the full CodePen&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Journey
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Finding the right metaphor
&lt;/h3&gt;

&lt;p&gt;My first version treated the page like a clean editorial index. It was readable, but it did not carry enough of the warmth, ceremony, and visual richness of the subject.&lt;/p&gt;

&lt;p&gt;The breakthrough was to stop treating biryani as a list of recipes and instead design an edible atlas. Each section became a different way to read the same dish: geography, cooking sequence, migration, flavour, and memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Researching the architecture
&lt;/h3&gt;

&lt;p&gt;The heritage direction was grounded in specific references rather than a generic ornamental style.&lt;/p&gt;

&lt;p&gt;I studied the &lt;a href="https://hyderabad.telangana.gov.in/tourist-place/charminar/" rel="noopener noreferrer"&gt;Charminar architecture described by Hyderabad District&lt;/a&gt;, particularly its four-sided arches, minarets, carved rings, and Qutb Shahi lotus details. I also looked at a &lt;a href="https://www.metmuseum.org/art/collection/search/453343" rel="noopener noreferrer"&gt;sixteenth-century Indian jali in The Metropolitan Museum of Art&lt;/a&gt;, where stars, hexagons, and interlocking geometry create a play of light and pattern.&lt;/p&gt;

&lt;p&gt;Those ideas became solid-color architectural frames, small lattice details, geometric rules, and the central handi illustration. I kept the interface modern by using strong editorial typography, square cards, clear hierarchy, and restrained motion.&lt;/p&gt;

&lt;h3&gt;
  
  
  Correcting the map
&lt;/h3&gt;

&lt;p&gt;The first map used a simplified world dataset and looked noticeably wrong. I replaced it with the official &lt;a href="https://surveyofindia.gov.in/pages/outline-maps-of-india" rel="noopener noreferrer"&gt;Survey of India 1:16m outline vector&lt;/a&gt;, including the island territories.&lt;/p&gt;

&lt;p&gt;The eight city points are projected from geographic coordinates instead of being positioned by eye. The map remains a cultural navigation device, but its outline and locations now have a defensible source.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building the interactions
&lt;/h3&gt;

&lt;p&gt;The project is a single responsive HTML document with inline CSS and vanilla JavaScript. CodePen separates those same three layers into its HTML, CSS, and JavaScript panels.&lt;/p&gt;

&lt;p&gt;JavaScript is used purposefully for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Switching regional map stories&lt;/li&gt;
&lt;li&gt;Updating cooking method diagrams&lt;/li&gt;
&lt;li&gt;Running and pausing the global biryani loop&lt;/li&gt;
&lt;li&gt;Filtering traditions by geography&lt;/li&gt;
&lt;li&gt;Comparing two traditions&lt;/li&gt;
&lt;li&gt;Updating the historical route&lt;/li&gt;
&lt;li&gt;Respecting reduced-motion preferences&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The page contains no raster food photography. The hero, diagrams, decorative architecture, and interface details are created with HTML, CSS, and inline vector geometry.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessibility and usability
&lt;/h3&gt;

&lt;p&gt;I wanted the atlas to remain useful beyond its visual impact. It includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Semantic sections and heading structure&lt;/li&gt;
&lt;li&gt;Keyboard-operable SVG map points&lt;/li&gt;
&lt;li&gt;Visible focus states&lt;/li&gt;
&lt;li&gt;A skip link&lt;/li&gt;
&lt;li&gt;Live regions for changing content&lt;/li&gt;
&lt;li&gt;Reduced-motion support&lt;/li&gt;
&lt;li&gt;Responsive layouts for narrow screens&lt;/li&gt;
&lt;li&gt;Source links for the research claims&lt;/li&gt;
&lt;li&gt;Clear notes where flavour scores are interpretive rather than scientific measurements&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I Am Proud Of
&lt;/h2&gt;

&lt;p&gt;I am most proud that the page does not rank biryanis or declare one authentic winner. It gives each tradition enough context to feel distinct while showing the shared ritual underneath: rice, patience, adaptation, and memory.&lt;/p&gt;

&lt;p&gt;The final result feels like a love letter, a research object, and a modern landing page at the same time.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI Collaboration
&lt;/h2&gt;

&lt;p&gt;I used OpenAI Codex as a collaborative coding, research, and iteration tool. I directed the concept, selected the biryani theme, reviewed each visual pass, identified inaccuracies, and made the final design decisions. The implementation and research sources were checked and refined through that collaboration.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>frontendchallenge</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>DUM: Breaking the Seal on Hyderabadi Biryani with Pure CSS</title>
      <dc:creator>Aditya</dc:creator>
      <pubDate>Sun, 02 Aug 2026 06:19:47 +0000</pubDate>
      <link>https://dev.to/adityakumarpuri/dum-breaking-the-seal-on-hyderabadi-biryani-with-pure-css-28d0</link>
      <guid>https://dev.to/adityakumarpuri/dum-breaking-the-seal-on-hyderabadi-biryani-with-pure-css-28d0</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/frontend-2026-07-29"&gt;Frontend Challenge - Comfort Food Edition, CSS Art&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspiration
&lt;/h2&gt;

&lt;p&gt;Hyderabadi dum biryani is more than a dish to me—it is a ritual. The sealed handi, the slow charcoal heat, the suspense before the atta crust is broken, and the first rush of saffron, mint, birista, and spice all feel inseparable from the experience.&lt;/p&gt;

&lt;p&gt;I wanted to turn that moment into an interactive midnight poster: Hyderabad’s skyline behind a copper handi, with the food hidden until the viewer breaks the seal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Click &lt;strong&gt;BREAK THE SEAL&lt;/strong&gt; to lift the lid and reveal the four biryani layers.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/editor/puri-adityakumar/embed/019fc0e2-b269-7487-be30-6e380fcb9616?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;The artwork is built with HTML and CSS only:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A native &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; / &lt;code&gt;&amp;lt;summary&amp;gt;&lt;/code&gt; control stores the open and closed states.&lt;/li&gt;
&lt;li&gt;CSS &lt;code&gt;:has()&lt;/code&gt; coordinates the seal crack, lid lift, layer reveal, steam, labels, embers, and state-aware copy.&lt;/li&gt;
&lt;li&gt;Rice grains, mint leaves, birista, spices, meat, copper patina, flour dust, the skyline, and the moon are all CSS shapes.&lt;/li&gt;
&lt;li&gt;There are no images, SVGs, canvas, JavaScript, gradients, or frameworks.&lt;/li&gt;
&lt;li&gt;A mobile composition and &lt;code&gt;prefers-reduced-motion&lt;/code&gt; keep the piece responsive and accessible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The reveal is deliberately choreographed:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;seal cracks → lid lifts → layers separate → labels arrive → steam settles&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Journey
&lt;/h2&gt;

&lt;p&gt;The hardest part was keeping the illustration detailed without losing the strong poster silhouette. I iterated on three areas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Material:&lt;/strong&gt; hammered copper marks, soot, flour residue, dough cracks, and print texture.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Depth:&lt;/strong&gt; curved food layers, overlapping grains, steam arches, and ingredient silhouettes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Motion:&lt;/strong&gt; a staged opening sequence rather than making every element animate at once.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The most satisfying decision was using a semantic HTML control for the interaction. The artwork still works with a keyboard, and disabling motion does not hide the final state.&lt;/p&gt;

&lt;p&gt;I used Codex as an iterative coding and visual-critique partner. I directed the concept, cultural references, composition, and final decisions, while the agent helped implement and test the CSS system.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I’m proud of
&lt;/h2&gt;

&lt;p&gt;The finished piece stays intentionally constrained: one HTML file, one CSS file, a small palette, and no image assets. The interaction adds drama, but CSS remains the star of the submission.&lt;/p&gt;

&lt;p&gt;Thanks for taking a look—and remember: patience is the final ingredient.&lt;/p&gt;

</description>
      <category>frontendchallenge</category>
      <category>devchallenge</category>
      <category>css</category>
    </item>
    <item>
      <title>AI Storyline Generator</title>
      <dc:creator>Aditya</dc:creator>
      <pubDate>Sun, 14 Sep 2025 21:49:45 +0000</pubDate>
      <link>https://dev.to/adityakumarpuri/ai-storyline-generator-3flp</link>
      <guid>https://dev.to/adityakumarpuri/ai-storyline-generator-3flp</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/google-ai-studio-2025-09-03"&gt;Google AI Studio Multimodal Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I created AI Storyline Generator, a web app that turns a set of images and a short text prompt into a cohesive narrative. It helps writers and artists quickly build stories or prototypes by offering three modes: Surprise Me (short story with optional cover art), Light Novel (full chapter with illustrations), and Manga (panel art).&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Demo Video&lt;/strong&gt;&lt;br&gt;
  &lt;iframe src="https://www.youtube.com/embed/d9XCAK-FJoM" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;br&gt;
&lt;strong&gt;Screenshots&lt;/strong&gt;&lt;br&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.amazonaws.com%2Fuploads%2Farticles%2Fzp0hr8a28v8of4af7app.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.amazonaws.com%2Fuploads%2Farticles%2Fzp0hr8a28v8of4af7app.png" alt="Screenshot-1" width="800" height="674"&gt;&lt;/a&gt;&lt;br&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.amazonaws.com%2Fuploads%2Farticles%2F6z5bkwgq0dpvv3u8t7pk.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.amazonaws.com%2Fuploads%2Farticles%2F6z5bkwgq0dpvv3u8t7pk.png" alt="Screenshot-2" width="799" height="677"&gt;&lt;/a&gt;&lt;br&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.amazonaws.com%2Fuploads%2Farticles%2Ftjjwiu2uqx951s8arkrr.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.amazonaws.com%2Fuploads%2Farticles%2Ftjjwiu2uqx951s8arkrr.png" alt="Screenshot-3" width="800" height="648"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  LINK
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://ai.studio/apps/drive/1LfupIv14tZuSoTqDvHD6yHBoHzgc0bgG" rel="noopener noreferrer"&gt;Applet Link 🌱&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Note: I was not able to publish the app due to billing issues. Please accept the published app link. Thankyou.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Google AI Studio
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Used gemini-2.5-flash-image-preview for vision–language tasks like story generation and all image outputs.&lt;/li&gt;
&lt;li&gt;Used gemini-2.5-flash for Manga mode to reliably create structured JSON scripts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Multimodal Features
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Image-to-Story Generation: Combines multiple images and text into a connected plot.&lt;/li&gt;
&lt;li&gt;Narrative-Aware Illustration: Generates key-scene illustrations directly from the AI-written story.&lt;/li&gt;
&lt;li&gt;Automated Manga Pipeline: Creates a full manga page by chaining image analysis, JSON scripting, and panel art generation&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>devchallenge</category>
      <category>googleaichallenge</category>
      <category>ai</category>
      <category>gemini</category>
    </item>
    <item>
      <title>Efficient Architecture 101: Is Your Upload Strategy Actually Efficient?</title>
      <dc:creator>Aditya</dc:creator>
      <pubDate>Tue, 26 Aug 2025 17:15:06 +0000</pubDate>
      <link>https://dev.to/adityakumarpuri/efficient-architecture-101-is-your-upload-strategy-actually-efficient-j17</link>
      <guid>https://dev.to/adityakumarpuri/efficient-architecture-101-is-your-upload-strategy-actually-efficient-j17</guid>
      <description>&lt;h2&gt;
  
  
  Before we start...
&lt;/h2&gt;

&lt;p&gt;So, why this series? I've recently jumped straight into the complexities of system design, and I think the best approach to learning is by writing blogs and sharing what I have learned. My goal is to create simple blogs with humor and a lot of diagrams. Please note, I'm still learning, so if you're experienced and find something that can be improved or is incorrect, please share your thoughts.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge: A Real-World Bottleneck
&lt;/h2&gt;

&lt;p&gt;Not long ago, I was digging through a codebase and found a classic file upload setup. The user would select a file in their browser, the browser would send it to our backend server, and &lt;em&gt;then&lt;/em&gt; the server would upload it to a cloud storage bucket like AWS S3.&lt;/p&gt;

&lt;p&gt;It worked, but it was far from efficient. The architecture looked something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0a5qvwoztmbdjrss4ddu.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.amazonaws.com%2Fuploads%2Farticles%2F0a5qvwoztmbdjrss4ddu.png" alt=" " width="381" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  So, approach has some serious drawbacks
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It's Slow for the User:&lt;/strong&gt; The file has to make two trips over the internet. The user is stuck waiting for both to complete.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It Hogs Server Resources:&lt;/strong&gt; Imagine 100 users uploading large videos at once. Your server is suddenly trying to process gigabytes of data, choking its memory, CPU, and bandwidth. This is a classic scalability nightmare.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It Can Be More Expensive:&lt;/strong&gt; You're paying for the bandwidth twice – once for the data coming into your server, and again for it going out to the cloud storage. Ouch.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A Slightly Better Approach (That's Actually Worse)
&lt;/h2&gt;

&lt;p&gt;So, to fix the speed issue, why not just upload directly from the browser? Modern tools like the AWS SDK for JavaScript let you do just that. The flow seems simpler and faster.&lt;/p&gt;

&lt;p&gt;But this comes with a giant, flashing, red security warning. To allow the browser to upload, you have to embed your secret access keys directly in the frontend code. This is like leaving the master key to your entire house under the doormat.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fft9src89bcir9prpplfh.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.amazonaws.com%2Fuploads%2Farticles%2Fft9src89bcir9prpplfh.png" alt=" " width="322" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anyone with a little know-how can open their browser's developer tools, find your keys, and gain full, unrestricted access to your storage bucket. It's a disaster waiting to happen.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Solution: Pre-Signed URLs
&lt;/h2&gt;

&lt;p&gt;This is where we get the best of both worlds: the speed of a direct upload and the security of a server-managed process.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A &lt;strong&gt;pre-signed URL&lt;/strong&gt; is a special, temporary, and secure link that your server generates. It gives a user permission to perform a &lt;em&gt;specific action&lt;/em&gt; (like uploading a file with a specific name) directly to your cloud storage, but only for a limited time.&lt;/p&gt;
&lt;/blockquote&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.amazonaws.com%2Fuploads%2Farticles%2Frufi0ch96t3i72jbne5p.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.amazonaws.com%2Fuploads%2Farticles%2Frufi0ch96t3i72jbne5p.png" alt=" " width="719" height="680"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;the browser first asks the server for permission. The server then generates a temporary, pre-signed URL and sends it back. The browser uses this special URL to upload the file directly to cloud storage. The server's only job is to authorize the request, not to handle the heavy file transfer itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, Why prefer pre-singed url for uploads?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Security:&lt;/strong&gt; Your cloud storage credentials are never exposed on the client-side.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved Performance:&lt;/strong&gt; Files are uploaded directly to cloud storage, reducing latency for the user.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Increased Scalability:&lt;/strong&gt; Offloads the bandwidth and processing load from your server, allowing it to handle more application requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost Optimization:&lt;/strong&gt; Reduces egress bandwidth costs from your server.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use Short-Lived URLs:&lt;/strong&gt; Always configure pre-signed URLs with the shortest possible expiration time (e.g., 5-15 minutes) to minimize the risk of misuse.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Utilize Multipart Uploads:&lt;/strong&gt; For large files, leverage multipart uploads. This involves generating multiple pre-signed URLs to upload the file in chunks, which improves reliability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement Resumable Uploads:&lt;/strong&gt; In case of network interruptions, a robust implementation should allow the upload to resume from the last successfully uploaded part, rather than restarting the entire process.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
  </channel>
</rss>
