{"componentChunkName":"component---src-templates-blog-post-js","path":"/blog/2026-07-10-ai-across-the-avni-lifecycle/","result":{"data":{"site":{"siteMetadata":{"siteUrl":"https://avniproject.org","twitterHandle":"@avniproject"}},"post":{"id":"5b8eac2e-814c-5b02-8af9-51ef23ebea25","html":"<p>Yes, we use AI for basically everything. No, it hasn't replaced anyone. What follows is the honest, occasionally funny version — the commands we run, and the humans who still make the calls.</p>\n<p>We build and run Avni — open-source software 70+ organisations use to reach over a million people. We can't hire an engineer when a bunch of NGOs show up. So this year we handed AI the boring 80% of every job and kept the 20% that actually needs to be owned by a human.</p>\n<p>Here's the whole thing on one screen. Then the receipts.</p>\n<h2>The whole thing : on one screen</h2>\n<table>\n<thead>\n<tr>\n<th>Stage</th>\n<th>The command</th>\n<th>What AI does</th>\n<th>Who decides</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Scope</strong></td>\n<td><code>/analyse</code></td>\n<td>maps what the NGO needs, splits config vs code, estimates</td>\n<td>a person</td>\n</tr>\n<tr>\n<td><strong>Design</strong></td>\n<td><code>/spec</code> · <code>/spec-review</code></td>\n<td>reads the live code, drafts the spec, checks it against reality</td>\n<td>a person</td>\n</tr>\n<tr>\n<td><strong>Build</strong></td>\n<td><code>/implement</code> · <code>/code-review</code></td>\n<td>plans, writes the code + tests, reviews the diff</td>\n<td>a person</td>\n</tr>\n<tr>\n<td><strong>Release &#x26; QA</strong></td>\n<td><code>/test-charter</code> · <code>/capture-bug</code></td>\n<td>ranks what's risky, writes and fixes the tests, files the bug</td>\n<td>QA (the boss)</td>\n</tr>\n<tr>\n<td><strong>Support</strong></td>\n<td><code>/triage</code> · <code>/datafix</code></td>\n<td>reads the ticket, drafts the reply, writes the fix</td>\n<td>a person</td>\n</tr>\n<tr>\n<td><strong>Orchestrate</strong></td>\n<td><code>conductor</code></td>\n<td>pulls every open thread into one prioritised list</td>\n<td>a person</td>\n</tr>\n</tbody>\n</table>\n<p>Every row ends the same way: <strong>AI drafts, a human decides.</strong> That last column never changes. That's the whole trick.</p>\n<h2>Scope : what does this NGO even need</h2>\n<p>An NGO turns up wanting Avni for, say, a maternal-health programme. Before anyone writes a line of code, <code>/analyse</code> maps what they need onto what Avni already does — who gets tracked, the forms, the workflows, the rules — and sorts each piece into \"just configuration\" or \"actually needs code.\" <code>/impl-scope</code> turns that into a scoped estimate, calibrated against the fifty-odd setups we've already done instead of a number pulled from the sky.</p>\n<p>If we're not sure something's even possible, we build a throwaway prototype before we promise anyone a date. <strong>We decide what's in.</strong></p>\n<h2>Design : read the code, then write the spec</h2>\n<p>Here's the unglamorous secret: the spec is written <em>from the code</em>, not from memory. <code>/spec</code> has AI read the live codebase first — does the data model actually work the way we assume, does it sync the way similar features already do, what are we forgetting — and only then drafts the spec. <code>/spec-review</code> checks that draft back against real code across our repos: invented endpoints, missing pieces, will-it-survive-a-big-org. <code>/story</code> cuts it into work small enough that someone who's never seen Avni could pick it up.</p>\n<p>Boring? Extremely. It's also exactly why the next stage is fast. <strong>We sign it off.</strong></p>\n<h2>Build : straight to master, no ceremony</h2>\n<p>A story lands. <code>/implement</code> plans the change, writes the code and the tests against that plan, and the developer runs the thing to confirm it actually works — revolutionary, I know.</p>\n<p>Then the part people get weird about: <strong>we stopped reading diffs line by line.</strong> Every change gets an AI <code>/code-review</code> pass — the author runs it, a peer runs it again — and we argue with what it flags. We didn't fire the reviewers. We fired the ritual where a human squints at 400 lines at 6pm pretending to catch a race condition. Straight to <code>master</code>, no pull requests. The seatbelt isn't a merge gate — it's a design we agreed up front, plus a few reviews on every change after a compulsive shake-up, and finally a dummy test the developer runs themselves. <strong>A person still owns what lands.</strong></p>\n<h2>Release &#x26; QA : test what's scary, skip what's not</h2>\n<p>In our QA repo, AI <em>wrote</em> the tests — Maestro flows for the Android app, Playwright for the web console — and, more usefully, it <em>validates them against the live app and fixes them when they break</em>, telling a real regression apart from a flaky script. One of those harnesses drove the real web console against production, tailed the server log (read-only) alongside, and caught a template action that blew up with an HTTP 500 nobody had managed to reproduce. When something breaks in the field, <code>/capture-bug</code> turns \"sync spins forever, here's a screenshot\" into a proper report with the suspect commit already named, and <code>/diagnose</code> chases the root cause. <code>verify_release.py</code> then does the unglamorous border check: is every story really done, did the code actually land on the release branch, did anything sneak in that belongs to next month. <strong>QA calls what ships.</strong></p>\n<h2>Support : a ticket, minus the busywork</h2>\n<p>A support ticket lands. <code>/triage</code> reads it, works out whether it's a settings mix-up, a data problem, or a real bug, and drafts the reply in plain language — no jargon, no internal IDs, no personal data.  <code>/report</code> drafts read-only analytics and never touches a live dashboard. And <code>/datafix</code>, the one place data actually gets corrected, only ever <em>writes a SQL file</em> for a human to review and run — there is no write connection to any database in that workspace at all.</p>\n<p>AI does the reading and the drafting. <strong>A human hits send, and a human runs the fix.</strong></p>\n<h2>Orchestrate : the part that runs the humans</h2>\n<p>This is the one that surprises people — and honestly the heaviest AI use of the lot.</p>\n<p>Running a platform this size, the work never arrives in one place. A request shows up on a task board, another in email, a third in a chat message, a fourth in some checklist nobody's opened in a month. Just keeping track of it all is a full-time job on its own.</p>\n<p>So we don't. <code>conductor</code> is an AI that reads every one of those places for us, spots when the same thing is sitting in four of them, and hands back a single ranked list: here's what's genuinely urgent, here's what only <em>feels</em> urgent, here's what can wait. Then <code>conductor-execute</code> takes the items that are really just \"go write something\" — an estimate, a short analysis, a reply — and drafts them ahead of time, with a second AI checking the first one's work, so we start from a draft instead of a blank page.</p>\n<p>The catch is the whole point: it never actually decides anything. The moment it can't tell whose job something is, it stops and asks. <strong>The human is the only thing that decides.</strong></p>\n<h2>What it looks like : a normal afternoon</h2>\n<p><figure class=\"gatsby-resp-image-figure\" style=\"\">\n    <span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1600px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/69c973fc07eba539e1a44e4928a847e5/29007/lifecycle.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 62.5%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAABMklEQVQoz2VSWZaEIBDjFLIKyKIC6vP+p5ug0zbS+QJCakkV2bbtOI51XadpEkLIBkqpbSs552VZKit7kFJKSgniNQaIKaXsAy5ELhnMrXdGM/ZlAbLve4zRWhuiM2ZsxcA8zwgN5ZpQmmVvkPM8offeu6CdVS8tZ5ClD7QxXWiiNR4r0BLnouU455Nz6BZ14QOufWZGhyceSNoAL1LCB47zMAz0B2SZPaLK65esyb8QnM9+iiE45/QFDKD9QDAqNGZrZRoRXmIhUq6A4XAOtqAB1opzrmbAzLREPY6tI6ARFzKMAwejFe9GFWPIuawpKa1R+OMKWkLmukJ7wRZhIuiuN6wabSfjghx1x0HsL8BwbBs8+HH7StOtzpP8Nvm59mKrxI3bg24YRnEl/9l7eVv8AUtvV3J5g4myAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Four terminal sessions, each doing a different kind of AI-assisted work across the lifecycle — scoping a new deployment, building a feature, release QA, and triaging a support ticket\"\n        title=\"Four terminal sessions, each doing a different kind of AI-assisted work across the lifecycle — scoping a new deployment, building a feature, release QA, and triaging a support ticket\"\n        src=\"/static/69c973fc07eba539e1a44e4928a847e5/29007/lifecycle.png\"\n        srcset=\"/static/69c973fc07eba539e1a44e4928a847e5/01e7c/lifecycle.png 512w,\n/static/69c973fc07eba539e1a44e4928a847e5/2bef9/lifecycle.png 1024w,\n/static/69c973fc07eba539e1a44e4928a847e5/29007/lifecycle.png 1600w\"\n        sizes=\"(max-width: 1600px) 100vw, 1600px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n  </a>\n    </span>\n    <figcaption class=\"gatsby-resp-image-figcaption\">Four terminal sessions, each doing a different kind of AI-assisted work across the lifecycle — scoping a new deployment, building a feature, release QA, and triaging a support ticket</figcaption>\n  </figure></p>\n<p><em>Four kinds of work at once — scoping, building, testing, triaging — a person on the end of every one.</em></p>\n<h2>The honest part : what's still hard</h2>\n<p>None of this comes for free, and the failure we watch for hardest is our own. AI writes a spec that reads beautifully and is quietly wrong, and a confident, fluent answer is the easiest kind to wave through. The review gates exist for exactly that — us trusting good writing too fast.</p>\n<p>It's also brilliant where there's a pattern to copy and merely okay where there isn't. Give it a feature with close cousins already in the codebase and it flies; ask for something genuinely new, or the estimate that rides on it, and the judgement is still ours. And the lesson we paid for: it has to work from the real code, not from memory. Left to recall how the system behaves, it will tell you confidently, and be wrong.</p>\n<h2>The Q&#x26;A : what people actually ask</h2>\n<p><strong>Did you fire everyone and let a robot do it?</strong>\nNo. We fired the boring parts. The people are all still here, doing the 20% that needed them the whole time.</p>\n<p><strong>When does it screw up?</strong>\nConstantly, confidently. It'll write a spec that reads great and is wrong, or a fix that's subtly off. That's the entire reason nothing ships on the AI's say-so.</p>\n<p><strong>Honestly, how much of this is you and how much is the AI?</strong>\nThe typing is mostly AI. The judgement is mostly us. Turns out the second one was the actual job all along.</p>\n<h2>Under the hood : the tooling</h2>\n<p>For the people who scrolled straight here — the stack:</p>\n<ul>\n<li><strong>The code</strong> is open source across roughly ten repos at <a href=\"https://github.com/avniproject\">github.com/avniproject</a>: the Android app, the server, the web console, the reporting pipeline, the rules and the infra.</li>\n<li><strong>The agent</strong> is Claude Code (Anthropic), on Opus and Sonnet, working straight against those repos.</li>\n<li><strong>The commands</strong> above — <code>/analyse</code>, <code>/implement</code>, <code>/triage</code>, <code>conductor</code> and friends — are our own reusable <em>skills</em> and multi-agent <em>workflows</em>: the pipeline, written down, so anyone on the team is one word away from it. For the engineering habits underneath, we lean on the open-source <em>superpowers</em> toolkit rather than reinventing them.</li>\n<li><strong>The reach</strong> is via MCP — the agent talks to GitHub, Google Workspace, a real browser for testing, and read-only production data. Never a write connection where it shouldn't have one.</li>\n</ul>\n<p>Most of it is public. The ops repos that run our day-to-day (<code>avni-product-ops</code>, <code>avni-support-ops</code>, <code>avni-qa</code>) are a mix of public and private, but the working style is identical: written down, versioned, reviewed before it runs. If any of it's useful to your team, get in touch — we're glad to share how it works.</p>\n<hr>\n<p><em>DISCLAIMER : <em>This blog was written using AI, inspired by Kevin Hart. If you got any problems with that, you know where to find me.</em></em></p>","frontmatter":{"date":"July 10, 2026","title":"AI in Samanvay : How we actually build and run the Avni platform now","author":"Himesh R","description":"The honest, mildly funny version of \"we use AI to build software.\"","tags":["AI","Software Engineering","Tech4Dev","Social Impact"],"image":{"childImageSharp":{"resize":{"src":"/static/69c973fc07eba539e1a44e4928a847e5/f3583/lifecycle.png","height":750,"width":1200}}}},"fields":{"slug":"/blog/2026-07-10-ai-across-the-avni-lifecycle/"}}},"pageContext":{"id":"5b8eac2e-814c-5b02-8af9-51ef23ebea25"}},"staticQueryHashes":["1175525803","4080856488"]}