<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Guru Banavar on Medium]]></title>
        <description><![CDATA[Stories by Guru Banavar on Medium]]></description>
        <link>https://medium.com/@guruduth.banavar?source=rss-1e6cc7621199------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*gTh4GKafBysVPPoTS-NK9w@2x.jpeg</url>
            <title>Stories by Guru Banavar on Medium</title>
            <link>https://medium.com/@guruduth.banavar?source=rss-1e6cc7621199------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 06:02:04 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@guruduth.banavar/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Spec-Driven AI Development: 
Engineering Discipline for the AI Coding Era]]></title>
            <link>https://medium.com/@guruduth.banavar/spec-driven-ai-development-engineering-discipline-for-the-ai-coding-era-22a678067b1c?source=rss-1e6cc7621199------2</link>
            <guid isPermaLink="false">https://medium.com/p/22a678067b1c</guid>
            <dc:creator><![CDATA[Guru Banavar]]></dc:creator>
            <pubDate>Tue, 28 Apr 2026 23:18:54 GMT</pubDate>
            <atom:updated>2026-04-29T04:28:17.906Z</atom:updated>
            <content:encoded><![CDATA[<p><em>How our team of engineers upgraded to a spec-driven methodology that ships faster, tests deeper, documents rigorously, and produces maintainable systems.</em></p><p>AI tools for software development have completely transformed the discipline of software development. Back in the mid-90’s I used to joke with my colleagues saying “how fast can you type?”. But now, when AI can write most of your code, the hard part is no longer typing. It is <em>deciding</em> — clearly and completely — <em>what</em> you want built.</p><p>I lead engineering and scientific work at Viome. Over the past several months, I have migrated my entire team — more than twenty people, spanning backend, frontend, data, and scientific engineering — to a methodology we call Spec-Driven AI Development, or SDAD. This post explains what it is, why it works, and how we run it day to day.</p><p>I am writing this for engineering leaders, individual engineers, and technical founders who are watching AI tools change their craft and want a serious answer to the question: <em>what does engineering look like when models write the code?</em></p><p>The short answer: it looks like writing <em>specifications</em>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mSPxIQEoY9Fl92RMWkpeWg.png" /><figcaption><strong>The Ladder of Abstraction</strong>: From Machine Language to Higher Level Languages to Declarative Languages to English as the Specification Language</figcaption></figure><h3>The problem with vibe coding</h3><p>Most teams using AI to write code today are doing what is now widely called <em>vibe coding</em> — chatting with a model, iterating on prompts, accepting code, fixing it, and repeating until something works.</p><p>Vibe coding has obvious appeal. It is fast at the start. It feels productive. For prototypes or one-off scripts, it is great.</p><p>For production code, vibe coding has serious failure modes:</p><ul><li><strong>Output depends on prompt quality.</strong> Two engineers describing the same feature get different code, different architectures, different bugs.</li><li><strong>Knowledge stays in the chat.</strong> When the chat ends, the reasoning behind the code is gone. The next engineer to touch it has no idea why it was built that way.</li><li><strong>Testing is an afterthought.</strong> If you remember to ask, you get five or ten tests. Most of the time you forget.</li><li><strong>Security and architecture are reviewed casually, if at all.</strong> Nobody systematically asks whether the AI’s design is the right one for your system.</li><li><strong>It does not scale.</strong> Vibe coding’s failure modes compound when twenty engineers are all doing it differently.</li></ul><p>The deeper issue is that vibe coding inherits the worst habit of classical software engineering — knowledge in the engineer’s head — and adds a new failure mode: the model also does not remember what it did or why.</p><h3>What is SDAD?</h3><p>Spec-Driven AI Development is a methodology where engineers write detailed, structured specifications first — using AI tools to help draft, structure, and maintain those specs as they evolve. The specs are the source of truth. AI generates code, tests, and documentation from those specs. Humans review the result and are accountable for it.</p><p>Engineers using SDAD primarily produce specifications, not code. The specs are versioned in git, evolve over time, and serve as both the system requirements as well as the documentation. When the code drifts from the spec, the spec wins — we update the code to match, or we update the spec deliberately and re-derive.</p><p>This sounds bureaucratic when written down. In practice it is the opposite. Once a team gets fluent with SDAD, projects move dramatically faster than under traditional development, with five times the test coverage and a measurable drop to zero production bugs on most launches. See the worked numbers in <em>What a typical project looks like</em>, below.</p><h3>Four principles</h3><p>SDAD rests on four principles. They are non-negotiable. If a project skips one of them, it is not SDAD; it is something else.</p><p><strong>Specification first.</strong> Expected behaviors, edge cases, constraints, and non-functional requirements are captured before any code is written. You do not leave the requirements to chance. If you discover something you wanted halfway through the build, you update the spec and start again.</p><p><strong>One source of truth.</strong> The spec anchors the entire project. Tests trace back to it. Documentation is derived from it. Architecture decisions live inside it. There is no second document somewhere with a different version of the truth.</p><p><strong>Built-in testability.</strong> Because the spec defines what done looks like, every requirement has an acceptance criterion. Developers, QA, and stakeholders share one standard.</p><p><strong>Iterative by design.</strong> Specs are not stone tablets. They evolve as design reviews, research, user feedback, and stakeholder input come in. But they evolve with traceability — every change has a version, a date, and a rationale.</p><p>That last point matters. Critics of spec-driven approaches often imagine the old waterfall model: lock the requirements, build for six months, ship something nobody wanted. That is not what SDAD does. Specs in SDAD are living documents. They change every day. The discipline is not in resisting change — it is in tracking change.</p><h3>SDAD vs classical software engineering</h3><p>You know the contrast already, but for the record: classical SWE puts a human at the keyboard with knowledge in their head, tests squeezed in at the end, bugs found in QA or production. SDAD inverts every line of that — humans write specs, AI writes the code, knowledge lives in versioned files, tests are exhaustive, bugs are found before production. The undervalued benefit is onboarding: a new engineer reads the spec, not the codebase. A good devspec explains <em>what the system does and why</em> in two thousand words. Reading the equivalent code takes days.</p><p>In the old days, we specified a program’s behavior by writing directly in machine language, like for the Intel 8085 processor. Then we specified it in a “high-level language” like C/C++, and let the compiler generate machine language. We continued raising the levels of abstraction in Java, and in declarative languages like SQL, and let runtime engines interpret the specifications. Now it’s time to specify a program’s behavior in natural language, English, and let an AI engine generate the executable code, in pretty much any language.</p><p>Even for your English specification, there is no substitute for clarity and completeness — if your English specification is ambiguous or incomplete, you are leaving your program’s behavior to whatever your AI engine decides.</p><h3>SDAD vs vibe coding</h3><p>This is the comparison that matters most to teams already using AI.</p><p>Vibe coding is conversational and ad-hoc. SDAD is systematic and reproducible.</p><p>Vibe coding will produce different results across engineers, or same engineer at different time points. SDAD produces the same results reproducibly regardless of who runs the spec.</p><p>Vibe coding leaves no documentation. The SDAD spec <em>is</em> the documentation.</p><p>Vibe coding tests what the engineer remembers to test. SDAD tests what the testspec says to test, which is everything in the devspec.</p><p>Vibe coding reviews security and architecture casually. In SDAD, security and architecture review are mandatory checkpoints. Human engineers cannot skip these.</p><p>The most important difference: vibe coding is bounded by the engineer’s working memory. SDAD is bounded by the engineer’s writing.</p><h3>Four artifacts</h3><p>Every SDAD project produces four core artifacts. The boundaries between them are clear from day one.</p><p><strong>The PRD (Product Requirements Document)</strong> defines the <em>what</em> and the <em>why</em>. Personas, KPIs, milestones, non-goals. The PRD is conceptual — it does not tell you how the system is built. A one-page PRD prevents weeks of scope drift.</p><p><strong>The DEVSPEC (Development Specification)</strong> defines what gets built, how it must behave, and in what order. It translates the PRD’s goals into functional requirements, non-functional requirements, implementation guidance, and a record of resolved decisions. The devspec is the source of truth for system behavior.</p><p><strong>The UISPEC (UI Specification)</strong> defines the user-facing surface — every screen, every command, every state, every status-dependent visibility rule, every acceptance criterion in Gherkin. The uispec references the devspec for behavior; the devspec does not duplicate UI states.</p><p><strong>The TESTSPEC (Test Specification)</strong> defines how to verify the devspec and uispec requirements. Test cases, fixtures, dry-run protocols, build-and-test sequences, validation criteria. The testspec supports the other three — it does not drive them.</p><p>The four artifacts form a directed chain. Devspec, uispec, and testspec all reference back to the PRD. The uispec references the devspec for behavior. The testspec references both the devspec and the uispec for authoritative definitions. Information flows in one direction.</p><p>Three rules govern this chain.</p><p>First, <strong>the PRD is stable</strong>. It does not reference devspec, uispec, or testspec filenames. Specs come and go; the PRD endures.</p><p>Second, <strong>the devspec drives implementation; the testspec supports it</strong>. Build modules in the order the devspec specifies. Use the testspec to verify each one. If the testspec’s organization suggests a different sequence, the devspec wins.</p><p>Third, <strong>behavior lives in the devspec; presentation lives in the uispec</strong>. When the same fact appears in both, the devspec wins and the uispec references it.</p><h3>What is in a devspec</h3><p>A devspec has four top-level parts and roughly fifteen sections. Some are mandatory; some are project-dependent. A lean devspec that covers the mandatory sections well beats a bloated one with every section filled in.</p><p><strong>Part I — Functional Requirements.</strong> The Overview, Data Schema, and a Module section per major component. Each module has a Goal, a list of Tasks, and an Exit Criterion that is measurable — a number, a file, a pass/fail. This is the heart of the spec. UI surfaces — screen layouts, state machines, visibility rules — live in the uispec, not in the devspec’s module sections.</p><p><strong>Part II — Non-Functional Requirements.</strong> Design principles. Error handling. Constraints (compute, regulatory, scope). Risks and mitigations.</p><p><strong>Part III — Implementation Guide.</strong> Directory structure with an artifact-lifecycle table classifying every directory as versioned, ephemeral, or durable. Environment and config. Technology stack with rationale. Runbook from a clean machine. Deliverables per milestone.</p><p><strong>Part IV — Appendices.</strong> Open Questions with a Blocks column. Resolved Decisions with rationale and date. Out of Scope. Changelog in descending order. A Lessons Log capturing what we discovered during implementation.</p><p>A few sections deserve special mention.</p><p>The <strong>Open Questions</strong> section forces discipline. Before writing the data schema, you list every question you do not yet have an answer to. <em>Which data source? What schema? What split? Local computation or remote API?</em> You answer these one at a time. Resolved questions migrate to the Resolved Decisions appendix with a date and a rationale, so we never re-litigate the same decision three weeks later.</p><p>The <strong>artifact lifecycle table</strong> answers a simple question for every directory: can this be regenerated from the versioned repo in under a minute, expensively, or not at all? The first goes in .gitignore. The second is committed. The third is gitignored and backed up separately. Trained model weights are durable. Inference audit logs are durable. Synthetic training data is versioned. Downloaded raw data is ephemeral. Most projects get this wrong by default.</p><p>The <strong>Lessons Log</strong> captures, in real time, what assumption turned out to be wrong. We do not summarize or polish it. The raw record is more valuable than a clean narrative. At every major version transition, lessons are classified — already integrated, needs strengthening, or moved to the troubleshooting FAQ — and the log is processed and removed. The goal is a self-contained spec. A reader of v2 should not need to read the v1 lessons log to understand the system.</p><h3>The SDAD process</h3><p>A typical SDAD project runs in five steps.</p><p><strong>Step 1: Specification.</strong> One engineer writes the devspec and uispec, with AI tools assisting on structure, cross-references, and changelog hygiene. AI generates a draft testspec from both. A different engineer — never the devspec author — owns the testspec from there and writes the cases the devspec author would not have thought to test. Two perspectives, expanded coverage, reduced author bias.</p><p><strong>Step 2: AI Code Generation.</strong> The AI generates code from the devspec — entities, repositories, services, controllers — and from the uispec — frontend types, hooks, components. In our experience, around 70 percent of the code is generated automatically. The remaining 30 percent is manual refinement of the spec or the code.</p><p><strong>Step 3: Test Generation and Iteration.</strong> The AI generates tests from the testspec, runs them, and finds bugs. Humans and AI fix bugs iteratively, updating the devspec first, then the uispec, then the testspec when a bug exposes a spec defect rather than a code defect. We do not consider the project done until every test passes.</p><p><strong>Step 4: Human Engineer Review.</strong> This step is mandatory and cannot be skipped. Security review. Architecture validation. Business logic verification. The human is the last line of defense, and is accountable for the deliverable.</p><p><strong>Step 5: Deploy to production.</strong></p><p>The whole process is gated by the test suite and the human review. Nothing ships without both.</p><h3>What a typical project looks like</h3><p>A representative project from the last year: a multi-module modernization of our provider portal — nine feature modules, a hierarchical RBAC system, a zero-downtime refactoring of fifteen database tables, a Java/Spring Boot backend, a React/TypeScript frontend.</p><p><strong>Traditional development — four to six months</strong></p><ul><li>Eng leads break the work into nine epics and assign engineers (1–2 weeks)</li><li>Engineers write code feature by feature with PR reviews (12–16 weeks)</li><li>QA finds 30–50 bugs across the surface (2–4 weeks)</li><li>Bug fixes, regression cycles, deploy windows (4–6 weeks)</li><li>Result: 4–6 months, ~50–100 tests, 1–3 production incidents</li></ul><p><strong>SDAD — weeks</strong></p><ul><li>Lead engineer writes eleven devspecs and ten testspecs across nine features — thousands of lines of specification, ~380 test cases</li><li>AI generates 80+ percent of the code from the specs (the engineer’s time is spent mostly in writing the spec and reviewing)</li><li>AI generates and runs the test suite; bugs are found and fixed in the spec-then-code loop</li><li>A different engineer owns each testspec and surfaces failure modes the devspec author missed</li><li>Lead engineer reviews security and architecture; all reviews pass first time</li><li>Result: weeks, ~380 tests, zero production incidents, RBAC in versioned specs</li></ul><p>The most striking difference is not the speed — it is the bug curve. SDAD finds bugs before production because the test suite is exhaustive by design, not by what the engineer remembered to test. The second most striking difference is the documentation: in traditional development, the RBAC matrix lives in someone’s head and a half-finished Confluence page. In SDAD, the matrix is the spec.</p><h3>Disciplines that make SDAD work</h3><p>SDAD is more than a process for writing specs. It is a set of disciplines that, together, make spec-driven work reliable. We learned these the hard way, on real projects.</p><p><strong>Versioning the spec like code.</strong> Specs use semantic versioning. Patch (1.x.y → 1.x.y+1) for typos and clarifications. Minor (1.x → 1.x+1) for new sections or significant content. Major (1.x → 2.0) creates a new file. Never skip a version number. Every revision gets a changelog entry with a date and summary. Changelogs run in descending order, newest first. On the molecular analysis tool from earlier, the PRD reached v2.76 and the devspec v2.62 with no skipped numbers across sixty-plus revisions. The bookkeeping pays off the first time you need to bisect a behavior change between v2.41 and v2.43 — a question you can answer in thirty seconds.</p><p><strong>Cross-section consistency audits.</strong> Some values appear in many sections and drift as the spec evolves. Field counts. Split percentages. Sample counts. Script names. Model paths. We grep for any numeric constant that appears in more than two sections and verify they match. They never match by default. They always match after the audit. In practice, AI tools run this audit for us — they catch numeric drift, stale variable names, and orphaned cross-references in seconds, across every section. On the same project, an audit caught a stale “65k” in an early devspec draft — the canonical sample count was 67.5k everywhere else. It also caught a — phase flag hanging on in two places after the entire CLI had moved to — steps. Both would have shipped without the audit.</p><p><strong>Two-tree synchronization.</strong> The devspec maintains two directory trees in parallel. A <em>functional tree</em> describing what the source repo contains by purpose, and an <em>implementation layout</em> describing what we actually scaffold with annotations. New files added to one must be added to the other. Drift between these trees is the most common source of “I forgot to commit a file” bugs.</p><p><strong>The pre-scaffold pass.</strong> Before writing any implementation code, we run a final audit. Does every directory in the functional tree appear in the implementation layout? Does every script in the dry-run table exist in the functional tree? Does every test file in the testspec appear in the functional tree? Does the build config include every package? Does .gitignore cover every gitignored path? Run this pass twice — the second pass finds issues the first one creates. Before the v0.4.0 distribution build, the pre-scaffold pass caught an __init__.py missing in a planned subpackage, a pyproject.toml not exporting a new module, and a spec reference to a function name that had been renamed mid-design. Three line items, each one a “huh, why doesn’t it import” hour.</p><p><strong>Dependency validation before long runs.</strong> Any process that runs for more than thirty minutes — a training run, a large batch evaluation — must validate every external dependency before the loop starts. A failed API key after eight hours of processing is a full re-run. We test API keys, output paths, model checkpoint loads, and sleep prevention before the loop begins, not during.</p><p><strong>Crash-safe writes.</strong> Every long-running loop writes outputs incrementally, one record at a time, in an append-safe format like JSONL. Per-record progress logging with explicit flushing. We never defer logging to a summary at the end. If the process crashes at step 400 of 500, we need to know which records succeeded.</p><p>These disciplines look like overhead until the day you avoid losing a night of compute because a stop token was missing.</p><p>One more rule, and the most important: <strong>specs that are not committed are specs that will be lost</strong>. After every checkpoint, we update the specs to reflect what we discovered, and we commit. No exceptions.</p><h3>SDAD across project types</h3><p>SDAD is not just for backend services. We have run it across database migrations, backend services, full-stack features, ML pipelines, KTLO, and business intelligence. The mechanics shift; the discipline does not.</p><p>Three projects across the engineering surface make the case.</p><p><strong>A molecular analysis tool, single engineer.</strong> The tool grew from Python prototype to a 40,000-line, 118-file CLI distribution in 29 days, across four pilots and thirteen experiments. SDAD’s classify-before-you-report rule — separate degenerate model outputs from real ones before computing aggregate metrics — caught the most important failure of the whole project. Experiment three produced what looked like a clean win: Cohen’s d of +0.331 between the two patient cohorts. The QC column showed Spearman ρ between effect size and read depth at 0.852 across all 132 Pareto models. The optimizer was learning sequencing depth, not biology. We caught it because the testspec required us to plot effect size against confound metrics for every model, not just the headline number. Two experiments later, the optimizer was running depth confound as a third Pareto objective, with a hard threshold. Without that discipline, we would have shipped a depth-of-sequencing detector dressed up as a disease score.</p><p><strong>A provider portal modernization, team-led.</strong> A Java/Spring Boot + React/TypeScript modernization shipped nine feature modules — including a hierarchical role-based access control system with twenty-two permissions across five roles, and a zero-downtime database refactoring across fifteen tables. Eleven devspecs and ten testspecs, totaling about several thousand lines of specification and 380 documented test cases. Roughly 75 percent of the code was AI-generated. Zero production incidents on deploy. All security reviews passed first time. I was not on the keyboard for any of it. The lead was a senior engineer on my team. He worked from the SDAD templates and the reference specs without needing me to weigh in on the code, the architecture, or the deploy plan. That is what spec-driven discipline buys: a normally multi-month modernization shipped to production in weeks, without the leader reviewing PRs.</p><p><strong>A consumer subscription portal, frontend-heavy.</strong> A subscription management redesign — twelve user flows across landing, order details, skip, add or remove products, pause, cancel, shipping, and payment, with status-based UI rules (Active, Paused, Skipped, Cancelled) and a multi-step retention flow on cancel — was specified before the first React component was written. The uispec captured every Figma screen, every status-dependent visibility rule, every Gherkin acceptance criterion. The spec went through more than thirty numbered versions across two months. The discipline that mattered most was not version control — it was the post-implementation sync at v3.0.0, where we walked the spec line by line and updated every place reality had diverged from the original design. Renamed hooks, refactored route paths, deprecated retention steps, new APIs for holding patterns and maintenance mode — every drift captured back into the spec, dated, rationalized. The spec tells the truth about the system. That is the only kind of spec worth keeping.</p><p>The pattern across all three: AI is good at understanding existing code and connecting to existing data. The bottleneck is the human’s ability to specify what they want. A scientist who can spec the optimizer’s failure modes saves a depth-confound. A senior engineer who can spec a permission matrix ships an RBAC system without leader review. A frontend lead who can spec every status-dependent screen ships a complex retention flow with the spec still matching the code six weeks after launch.</p><h3>Templates do the heavy lifting</h3><p>No engineer at Viome starts from a blank document. We maintain a library of reference specs — one per artifact, with project-type variants — and every new project begins as a copy.</p><p>A backend devspec template differs from a frontend uispec template, which differs again from an ML devspec template. Each template encodes section structure, terminology, versioning, open-questions categories, and exit-criterion patterns. When a project discovers a useful pattern, that pattern lands in the template before the project closes.</p><p>The result: a new engineer’s first devspec is shaped by every lesson the team has learned. A new ML project asks about degenerate-output classification before training. A new frontend project specs status-dependent visibility rules in the uispec, not as scattered comments in React. A new backend project knows the testspec needs unit tests per module and integration tests per use case.</p><p>Templates are how SDAD scales beyond the engineer who invented it.</p><h3>Migrating a team of twenty</h3><p>Moving twenty-plus engineers to SDAD took deliberate work. Templates (above) made the cold start tractable. Two more things were essential.</p><p>First, on every project, the testspec is ideally written and managed by a different engineer than the one who wrote the devspec. This is structural, not stylistic: the testspec author asks questions the devspec author did not think to ask, names failure modes the devspec author did not see, and writes test cases the devspec author would not have written. Two perspectives expand coverage and reduce author bias. We pair onboarding engineers with seniors for their first few specs, but the cross-author discipline outlasts onboarding.</p><p>Second, every SDAD project produces a final metrics table — time to ship, test count, production bugs in the first thirty days, percent of code AI-generated, percent of bugs caught pre-deploy. We track these per engineer and per team, and we share them openly. The metrics make the case for SDAD better than any all-hands deck.</p><p>The one group I worried about was scientific engineering — the team building ML models, training pipelines, and bioinformatics tools. Scientists are trained to value experimental flexibility, and process-heavy approaches feel wrong to them.</p><p>What we found is that even scientific engineers (eg myself), once they tried SDAD, became committed users. The reason: data/ML projects fail in subtle, expensive ways. A placeholder prompt that gets baked into training. A stop token that appears in inference output. A stale data version that invalidates a week of evaluation. SDAD’s disciplines — open questions, lessons logs, dependency validation, the inference wiring checklist — catch these failures early. A scientist who has lost two days to a config bug might well become an SDAD evangelist.</p><h3>The anti-patterns SDAD prevents</h3><p>Each row of the table below is a story we could tell in detail from a real project. Three short ones, all from the same molecular analysis tool we discussed earlier:</p><p><strong>Cycle 14 of 20.</strong> A multi-hour cycle controller run on the optimizer crashed at cycle 14 of 20 when a joblib worker hit OOM. Without per-record progress logging and crash-safe JSONL writes, that crash would have lost the night’s compute. Instead, the run resumed at cycle 14 with one flag — every record before the crash was already on disk, in append-safe format, flushed after each write. The SDAD rule for long-running loops is dull: write outputs incrementally, log per-record, flush after every line. The bookkeeping looks like overhead until the day you crash at cycle 14 of 20.</p><p><strong>The 12,419-entry knowledge base.</strong> The same project maintains a knowledge base with 12,419 biologist annotations. The structure can be regenerated from KEGG metadata in minutes; the annotations cannot. SDAD’s artifact-lifecycle classification flagged the file as durable — gitignored from the bulk-regenerable parts but committed for the annotation overlays, and backed up separately. Without the classification, an early “let’s clean up generated artifacts” pass would have wiped weeks of biologist work. The rule is one question for every file in the spec: <em>can this be regenerated from scratch using only the versioned repo?</em> The answer goes in a three-column table, and the table is non-negotiable.</p><p><strong>The %CV that rejected every good model.</strong> Reproducibility scores were being computed on raw ICA factor scores, which center near zero. Coefficients of variation on near-zero numbers go astronomical. The reproducibility gate started rejecting every clean model. The fix was not just code — it was promoting the failure to a versioned requirement (“must use 0–100 scaled scores, not raw factor scores”) and recording it in the Resolved Decisions appendix with the date and the root cause. A future engineer or a future AI looking at the spec sees the rule and the reason. The rule: failures that are understood become acceptance criteria. Bugs that escape the lessons log are bugs that come back.</p><p>The list below catalogs the rest of our internal lessons-log entries — anti-patterns we have hit on real projects, and the SDAD discipline that prevents each one:</p><ul><li><strong>Anti-pattern: </strong>Scope creep mid-implementation<br><strong>SDAD</strong>: PRD and non-goals defined before spec</li><li><strong>Anti-pattern: </strong>Re-litigating architecture decisions<br><strong>SDAD</strong>: Resolved Decisions appendix with date and rationale</li><li><strong>Anti-pattern: </strong>Stale numeric constants across sections<br><strong>SDAD</strong>: Cross-section consistency audit</li><li><strong>Anti-pattern: </strong>Ephemeral files lost between sessions<br><strong>SDAD</strong>: Explicit ephemeral / versioned / durable classification</li><li><strong>Anti-pattern: </strong>Library named but API not specified<br><strong>SDAD</strong>: Module guides must name the exact function, not just the library</li><li><strong>Anti-pattern: </strong>Process crashes silently after hours<br><strong>SDAD</strong>: Per-record progress logging with explicit flushing</li><li><strong>Anti-pattern: </strong>Stop tokens appear in generation output<br><strong>SDAD</strong>: Inference wiring checklist</li><li><strong>Anti-pattern: </strong>Spec and implementation diverge<br><strong>SDAD</strong>: Two-tree sync and pre-scaffold audit</li><li><strong>Anti-pattern: </strong>V1 lessons buried in appendix<br><strong>SDAD</strong>: At major version boundaries, lessons fold into spec body</li><li><strong>Anti-pattern: </strong>Same fact documented in multiple places<br><strong>SDAD</strong>: Devspec is the single source of truth for system behavior</li><li><strong>Anti-pattern: </strong>Placeholder configs in training data<br><strong>SDAD</strong>: Write all prompts and configs before running the pipeline</li><li><strong>Anti-pattern: </strong>Degenerate outputs inflating failure counts<br><strong>SDAD</strong>: Classify outputs and report two metrics, not one</li></ul><p>Each item above represents days of debugging that we no longer do.</p><h3>The cultural shift</h3><p>The most underappreciated thing about SDAD is what it changes about the engineering role.</p><p>In classical SWE, an engineer’s value is measured in code. A 10x engineer ships ten times the lines. In SDAD, an engineer’s value is measured in clarity. A 10x engineer writes specs that anyone — including AI — can implement correctly the first time.</p><p>This is a different skill. Some engineers take to it immediately. Some struggle. The struggle is rarely about the tools; it is about being asked to write down, in advance, what they previously held in their heads. Engineers who think clearly love SDAD. Engineers who hide behind ad-hoc work resist it.</p><p>The good news: clear thinking is teachable. We see new engineers go from struggling with devspecs to publishable ones in two to three projects.</p><p>The harder news, from a hiring perspective: SDAD will widen the gap between engineers who can articulate what they are building and those who cannot. The most important skill for an engineer in 2026 is not knowing a particular language or framework. It is the discipline to write a spec a model can implement.</p><h3>Why this should be your standard too</h3><p>I am not pitching SDAD as one option among many. I strongly believe this is the right way to build software in the era of capable AI coding tools, and I think most engineering organizations will arrive at something like this within the next year or two.</p><p>The economics of code have changed. AI generates almost all of the code we write today. The question every engineering leader has to answer is: <em>what is the human doing?</em></p><p>If the answer is “the human is still typing the code, just with autocomplete on steroids” — that team is not getting the productivity gains it could be getting, and it is accumulating maintenance debt at a rate that will catch up to it.</p><p>If the answer is “the human is vibe coding” — that team is moving fast in the short term and building potentially unmaintainable systems in the long term.</p><p>The right answer is: the human writes specifications. AI writes the code. Humans review what AI produces. Tests gate the deploy. That is SDAD.</p><p>We have made SDAD the standard at Viome — every engineer, every project, every artifact in git, every project producing tracked metrics. I am writing this post in part to share what we have learned, and in part to make it easier for other teams to do the same.</p><p>The shift is not optional. The teams that adopt SDAD-like disciplines will out-build the teams that do not. The only question is how soon you start.</p><p><em>Guru Banavar is the founding CTO of Viome, where he leads engineering, AI, and platform development for scientific and clinical applications. He writes and speaks about the future of chronic diseases, AI, and software development.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=22a678067b1c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ChatGPT’s deep fake text generation is a threat to evidence-based discourse]]></title>
            <link>https://medium.com/@guruduth.banavar/chatgpts-deep-fake-text-generation-is-a-threat-to-evidence-based-discourse-c096164207e0?source=rss-1e6cc7621199------2</link>
            <guid isPermaLink="false">https://medium.com/p/c096164207e0</guid>
            <category><![CDATA[science]]></category>
            <category><![CDATA[health]]></category>
            <category><![CDATA[evidence]]></category>
            <category><![CDATA[misinformation]]></category>
            <category><![CDATA[chatgpt]]></category>
            <dc:creator><![CDATA[Guru Banavar]]></dc:creator>
            <pubDate>Sun, 11 Dec 2022 23:17:05 GMT</pubDate>
            <atom:updated>2026-04-28T22:12:31.025Z</atom:updated>
            <content:encoded><![CDATA[<h3>ChatGPT’s hallucinated text generation needs major overhaul for evidence-based discourse</h3><p>As an AI developer &amp; data science researcher for decades, I strongly believe in the potential of AI to do good for humanity. I have given many talks, including a <a href="https://www.bcs.org/events/turing-talk/2017-turing-lecture-beneficial-ai-for-the-advancement-of-humankind/">2017 Turing Lecture</a> about how humans and machines can and should co-exist in our new world order.</p><p>In the last 5+ years, I have focused my efforts on the domain of human health and disease, in particular to address the epidemic of chronic disease that inflicts &gt;50% of humanity in the 21st century. This is a complex field that requires robust biological science, big data (carefully collected and verified), and sophisticated AI &amp; ML to make meaningful advancements. And it requires a simple, honest, and evidence-based approach to communicating information to the general public. I believe we have made progress towards this goal in our company, <a href="https://www.viomelifesciences.com/">Viome Life Sciences</a>, with a <a href="https://www.viome.com/">suite of direct-to-consumer at-home products</a> that provide individualized science-based information to hundreds of thousands of people in over a hundred countries.</p><p>I was excited to see the release of the <a href="https://chat.openai.com/chat">ChatGPT</a> large language model (LLM) to the general public as another big step towards AI for good. ChatGPT is an example of a generative AI model trained using reinforcement learning with a large corpus. We are all mesmerized by this technology and of course, we wanted to see if it could be useful in the context of Viome. However, after evaluating it, I’m disappointed to say that it is far from being helpful in the health advice setting, and it could even be a significant threat to the evidence-based discourse needed in the field of health sciences.</p><p>The insidious nature of such generative AI models is that they produce <em>plausible</em> sounding health information in a smooth conversational style, that is at best is generic in nature and at worst completely fictional. The problem is that most people cannot tell the difference between the two. Since I understand the inner workings of these AI models, it’s unfortunately technically very hard if not impossible to separate the facts from the fiction, and explain the source of each piece of information generated. But an innocent user who is not versed in either AI or health sciences can easily get fooled into believing all the information provided by ChatGPT as being authoritative. In the worst case, they could practice it in their lives despite the warnings, potentially leading to disastrous consequences to their health and wellness.</p><p>I provide examples of this problem below. In the interest of getting this information out to the public, and to the developers at OpenAI, as soon as possible, I provide only a few examples from my early explorations in the last week or so. There will undoubtedly be many other examples as I and my colleagues dig deeper.</p><h3>Initially, ChatGPT impresses and establishes trust</h3><p>In a recent conversation, ChatGPT started off by providing some very good general advice and guidelines, and declining to provide specific individual meal plans. This has the effect of being reasonable and smooth, and establishes trust with the human user. This is indeed a key goal of ChatGPT — to be natural and conversational — which it achieves with excellent results.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/631/0*HwCc1ju_oUsGh6fH" /></figure><p>A lot has been studied and written about AI and trust building. Fundamentally, humans are wired to find a way to build trust with anything that can be plausibly anthropomorphic — whether it is a cute doll, a human-like robot, or an AI agent that seems to think like a human. Read more on this topic <a href="https://www.amazon.com/Human-Compatible-Artificial-Intelligence-Problem/dp/0525558632/ref=asc_df_0525558632/?tag=hyprod-20&amp;linkCode=df0&amp;hvadid=459440273404&amp;hvpos=&amp;hvnetw=g&amp;hvrand=6456958521679593630&amp;hvpone=&amp;hvptwo=&amp;hvqmt=&amp;hvdev=c&amp;hvdvcmdl=&amp;hvlocint=&amp;hvlocphy=9004259&amp;hvtargid=pla-951654604793&amp;psc=1">here</a>, <a href="https://link.springer.com/article/10.1007/s11948-020-00228-y">here</a>, and <a href="https://www.cambridge.org/core/journals/cambridge-quarterly-of-healthcare-ethics/article/misplaced-trust-and-distrust-how-not-to-engage-with-medical-artificial-intelligence/1E647A2F0898FF690F7B94F272331EA5">here</a>.</p><p>In this case, ChatGPT’s natural and conversational style has pre-conditioned the human user to trust it, or at least give it the benefit of the doubt. This trust-building is a significant element of my analysis because it could make people let down their guard and not be as skeptical of ChatGPT as they would be otherwise.</p><h3>ChatGPT is not shy to get into outdated specifics</h3><p>With the next question, ChatGPT gets into specific vegetables, fruits, grains, legumes, and protein sources, including the point at the bottom about monitoring portion sizes. All of this is generic information that you can find with some google searches. The human user is now starting to really trust this system.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/633/0*1ThWdxBcAs0GRGhZ" /></figure><p><em>Except that this is outdated information provided without context.</em> There is a significant amount of recent (last 8 years) research that establishes that blood sugar response is highly individual and not generic across all individuals. For example, two people eating bananas and rice can have opposite blood sugar responses — one of them high response for banana and low response for rice, and the other high response for rice and low response for bananas — depending on many ‘phenotypic’ features (like their age, sex, bmi, etc) and their gut microbiome (the multitudes of microorganisms, mainly bacteria that live in your intestines). It is inaccurate to say, like ChatGPT does above, that bananas should be avoided and brown rice should be consumed.</p><p>Our group at Viome has published these individualized blood glucose response results in a scientific paper in the journal <em>Diabetes Therapy</em> after a long and hard clinical study, <a href="https://pubmed.ncbi.nlm.nih.gov/34799839/">Gut Microbiome Activity Contributes to Prediction of Individual Variation in Glycemic Response in Adults</a>. And other groups around the world have also shown these results independently — <a href="https://www.cell.com/cell/fulltext/S0092-8674(15)01481-6?_returnURL=https%3A%2F%2Flinkinghub.elsevier.com%2Fretrieve%2Fpii%2FS0092867415014816%3Fshowall%3Dtrue">here</a>, <a href="https://jamanetwork.com/journals/jamanetworkopen/fullarticle/2723644">here</a>, and <a href="https://www.clinicalnutritionopenscience.com/article/S2352-9393(16)00002-6/fulltext">here</a> for example. ChatGPT does not mention or use any of this research.</p><p>It can be argued that the information put out by ChatGPT is generic conventional wisdom, so it is not seriously problematic, and that it is the nature of science to continuously unearth new and improved truths. Also, it will always be the case that there will be outdated information in vogue. After all, the medical practices from the last few centuries are still being practiced in some form by subgroups of people somewhere in the world. But this is precisely why we would like modern AI systems to help us in curating the most evidence-based and trust-worthy information! Just like Google ranks pages based on their relevance and significance, it is desirable for a state-of-the-art AI system to propagate state-of-the-art knowledge. If there are multiple views, a good AI should provide summaries of the major views, so the human user can do their own research, and come to their own conclusions. On these counts, ChatGPT is far behind.</p><h3>When pressed, ChatGPT literally makes up science fiction</h3><p>Unfortunately, ChatGPT does not stop at providing obsolete information — when asked specific questions about particular details, it provides a scientific sounding explanation that is a combination of facts and bullshit that no one can distinguish.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/726/0*2-0k1IYiB8kIqwBZ" /></figure><p>Superficially, this sounds highly authoritative, and you might take it at face value given the trust it has already built with you earlier in the conversation.</p><p><em>But this statement misunderstands my prompt about the gut, and answers the question in relation to the liver!</em> ChatGPT is providing a generic response from nutritional science, where avocado is considered safe to eat when there is high uric acid production in the liver. Then that paragraph goes on to say that avocado may help REDUCE uric acid, as shown by recent studies shown in the references.</p><p><em>And the most egregious part is that </em><strong><em>THE REFERENCES AT THE BOTTOM ARE ENTIRELY MADE UP</em></strong><em> — they don’t exist!!</em> The journals mentioned exist, but the specific articles don’t exist — the titles are made up, and the cited authors seem to be real people who are publishing on similar topics, although not specifically on gout, avocado, or uric acid. The second paragraph makes a strong claim that avocado may help reduce uric acid and provides a BOGUS scientific article as evidence.</p><p>I tried the same type of questions for other foods and gut chemistry, such as consuming turmeric when bile acid production is high in the gut, or eating onions when there is high sulfide gas production in the gut, and got a similar fictional narrative.</p><h3>First, do no harm</h3><p>This type of AI interaction with humans is a real threat to health in particular and science in general. In the field of health sciences, which exists to serve humanity, everyone explicitly (or implicitly) takes the Hippocratic oath of avoiding harm. The above interactions do harm at multiple levels.</p><p>If someone were to take the health advice seriously, develop complications, who is responsible? Yes, the article says at the end that the individual should take a doctor’s advice before making any changes, but a modern doctor can easily get swayed by this same misinformation as an individual consumer. Also a scientist in the field, unless they carefully research the conclusion, can get misled if they take this article at face value. And what about those scientists whose names are used in a fake article linked to a false claim — what are their rights regarding the integrity of their work?</p><p>ChatGPT in its current form is doing the opposite of serving humanity, at least in health sciences and related evidence-based fields. Neither is this ChatGPT interaction helping consumers reliably improve their health, nor is it helping experts advance health science. And what if this is co-opted by nefarious players to accomplish precisely planned disinformation?</p><p>ChatGPT is similar (but not identical) to the many “<a href="https://en.wikipedia.org/wiki/Deepfake">deep fake</a>” AIs in recent times for generating creative artistic images in the style of other people (eg <a href="https://openai.com/dall-e-2/">DALL-E</a>), or creative videos (eg <a href="https://www.synthesia.io/">Synthesia</a>), or <a href="https://en.wikipedia.org/wiki/Audio_deepfake">audio deep fakes</a>, which combine fact and fiction for infotainment or other purposes. While this application of deep fakes is highly impressive, it is not acceptable to generate misinformation at scale and create a potentially bigger problem than what it was intended to solve.</p><p>As a community of responsible innovators, the AI community must put some guardrails around use cases that deal with evidence-based domains. There are multiple ways to address this issue, such as ring-fencing highly sensitive use cases (it was banned from Stack Overflow), detecting AI generated content and tagging it, attributing sources when possible, developing fact-checking AI’s, and so on. <strong>The purpose of this article is to quickly shine a light on the problem and encourage the community to think about and suggest ethical ways of addressing this issue.</strong></p><p>I remain excited about the potential of AI to do good for humanity, and hope that we can continue to deploy ChatGPT for the use cases that it excels in!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c096164207e0" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>