<?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: Marvin Okafor</title>
    <description>The latest articles on DEV Community by Marvin Okafor (@marvinoka4).</description>
    <link>https://dev.to/marvinoka4</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%2F3374130%2F3bcbdf95-06f3-4f18-b203-2f0b9607a11c.png</url>
      <title>DEV Community: Marvin Okafor</title>
      <link>https://dev.to/marvinoka4</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/marvinoka4"/>
    <language>en</language>
    <item>
      <title>I Grade AI Agent Code for a Living. Here's the 12-Point Checklist I Run Before Trusting Any of It.</title>
      <dc:creator>Marvin Okafor</dc:creator>
      <pubDate>Mon, 07 Sep 2026 23:17:07 +0000</pubDate>
      <link>https://dev.to/marvinoka4/i-grade-ai-agent-code-for-a-living-heres-the-12-point-checklist-i-run-before-trusting-any-of-it-5adp</link>
      <guid>https://dev.to/marvinoka4/i-grade-ai-agent-code-for-a-living-heres-the-12-point-checklist-i-run-before-trusting-any-of-it-5adp</guid>
      <description>&lt;p&gt;Your agent produced 400 lines in nine seconds. It compiles. The tests pass. The demo works.&lt;/p&gt;

&lt;p&gt;None of that tells you whether it's correct.&lt;/p&gt;

&lt;p&gt;I evaluate agentic AI coding output against structured rubrics professionally - correctness, instruction adherence, edge-case handling, the whole grid. Separately, I've spent seven years shipping production systems: high-traffic e-commerce, multi-tenant healthcare data, a national eLearning platform handling tens of thousands of concurrent applications. The checklist below is what happens when those two things collide. It's the pass I run before I'll put my name on anything an agent wrote.&lt;/p&gt;

&lt;p&gt;None of it is exotic. All of it is stuff agents get wrong constantly, and reviewers skip because the code &lt;em&gt;looks&lt;/em&gt; fine.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. Does deleting the error handling break any test?
&lt;/h3&gt;

&lt;p&gt;If not, your error paths are untested decoration. This is the single fastest way to find out whether a test suite is real. Comment out a &lt;code&gt;catch&lt;/code&gt; block and run the suite. Green? You have no coverage of the thing most likely to hurt you.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. What happens on the second call?
&lt;/h3&gt;

&lt;p&gt;Agents write beautiful single-execution logic. Ask: if this runs twice - retry, duplicate message, user double-click - does it produce one side effect or two? Idempotency is seldom in the generated code unless you asked for it explicitly, and it's almost always required in production.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Is every dependency pinned, and does the lockfile exist?
&lt;/h3&gt;

&lt;p&gt;"Latest" is not a version. I've root-caused a bug where a &lt;em&gt;minor&lt;/em&gt; version bump silently collapsed TypeScript types to &lt;code&gt;never&lt;/code&gt; across a monorepo - semver protects runtime behaviour; it promises nothing about type inference or subtle behavioural edges. Agents love unpinned ranges. Pin them.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Is it mocking the thing it's supposed to be testing?
&lt;/h3&gt;

&lt;p&gt;The most common fake-coverage pattern I see: mock the database, assert the mock was called correctly, declare the data layer tested. If the correctness property is enforced by the database - constraints, row-level security policies, transaction isolation - a mock verifies your &lt;em&gt;assumption&lt;/em&gt; about the policy, not the policy. Run against a real, disposable instance. I maintain a security suite that validates RLS policies against actual Postgres for exactly this reason.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Does it check what should be &lt;em&gt;invisible&lt;/em&gt;, not just what's visible?
&lt;/h3&gt;

&lt;p&gt;Access-control tests written by agents almost always assert "the authorised user can see their data." The security-relevant half is "the unauthorised user &lt;em&gt;cannot&lt;/em&gt;." Test negative cases explicitly - and remember that some systems (RLS being the classic) filter silently rather than erroring, so "no exception raised" is not the same as "correctly denied." Assert the actual result set.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. How many database round-trips does the happy path make?
&lt;/h3&gt;

&lt;p&gt;ORMs plus agents produce N+1 queries at an impressive rate, because each line looks perfectly reasonable. Log the queries for one request. Count them. The number is usually higher than anyone guessed, and it's where a large share of real latency wins hide.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. What are the timeout and retry policies - explicitly?
&lt;/h3&gt;

&lt;p&gt;Not "does it retry," but: how many times, with what backoff, and what happens when retries are exhausted? Unbounded retries against a struggling downstream service is how a partial outage becomes a full one. Agents default to either no retries or naive infinite ones.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Does it handle partial failure, or only total failure?
&lt;/h3&gt;

&lt;p&gt;Total failure is easy - the call throws, you catch it. Partial failure is the hard case: three of five writes succeeded, the response timed out but the operation actually completed, the queue delivered twice. Generated code is overwhelmingly written as though operations either fully succeed or fully fail.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Are the IAM permissions scoped, or is it wildcards?
&lt;/h3&gt;

&lt;p&gt;Agents reach for permissive policies because permissive policies make the demo work. Any wildcard in a generated permission set is a finding, not a default. Same for over-broad database roles - a correct policy can still leak data if the connecting role has privileges that sidestep it.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Is there anything in here that only works because of a race the tests never trigger?
&lt;/h3&gt;

&lt;p&gt;Concurrency is where "semantically wrong about failure" gets most expensive. Check-then-act patterns, non-atomic read-modify-write, missing transaction boundaries. Tests run sequentially; production doesn't.&lt;/p&gt;

&lt;h3&gt;
  
  
  11. Can someone else reproduce this from a clean clone?
&lt;/h3&gt;

&lt;p&gt;One command, fresh machine, same result. If setup requires tribal knowledge or an undocumented sequence of steps, your correctness is unverifiable by anyone but you - which, for anything that will outlive your attention span, means it's unverified.&lt;/p&gt;

&lt;h3&gt;
  
  
  12. Is the reasoning written down anywhere?
&lt;/h3&gt;

&lt;p&gt;Which ambiguity did you resolve, and how? What did you deliberately not handle? Agents produce code without provenance - no record of what was considered and rejected. That gap is a real maintenance liability, because the next person can't distinguish a deliberate decision from an accident. Write down the &lt;em&gt;why&lt;/em&gt;, especially for the non-obvious calls.&lt;/p&gt;




&lt;h2&gt;
  
  
  The pattern underneath all twelve
&lt;/h2&gt;

&lt;p&gt;Every item is a variant of the same thing: &lt;strong&gt;agents are excellent at code and unreliable about consequences.&lt;/strong&gt; They handle the path you described and quietly assume the paths you didn't. The failure mode people complain loudest about - hallucinated APIs - is the easy one, because it's loud and any test catches it. The dangerous one is syntactically perfect code that's confidently wrong about what happens when something breaks.&lt;/p&gt;

&lt;p&gt;Which means the review skill that matters now isn't "can you spot bad code." It's "can you enumerate the failure modes nobody wrote down." That's not a new skill. It's the thing senior engineers have always done. It just got a lot more load-bearing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'm building from this
&lt;/h2&gt;

&lt;p&gt;I'm turning this checklist into something executable - a fault-injection harness that stress-tests agent-generated infrastructure code against realistic failure conditions (retries, partial outages, IAM misconfigurations, concurrent access) with deterministic pass/fail checks instead of eyeballing. Chaos engineering, pointed at AI output. It'll go up on my GitHub and portfolio as I build it in the open, along with what breaks and why.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's on your list that isn't on mine?&lt;/strong&gt; I'm collecting failure patterns for the harness's scenario set, and the ones that come from people who've been burned in production are worth more than anything I can invent. Drop them in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Part of an ongoing series on production debugging, performance engineering, and evaluation infrastructure for AI systems.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>codereview</category>
      <category>devops</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I Built an Agent to Fix Bad Tests. I Found Eight Bugs in My Own Ruler.</title>
      <dc:creator>Marvin Okafor</dc:creator>
      <pubDate>Tue, 01 Sep 2026 18:01:34 +0000</pubDate>
      <link>https://dev.to/marvinoka4/i-built-an-agent-to-fix-bad-tests-i-found-eight-bugs-in-my-own-ruler-1eap</link>
      <guid>https://dev.to/marvinoka4/i-built-an-agent-to-fix-bad-tests-i-found-eight-bugs-in-my-own-ruler-1eap</guid>
      <description>&lt;p&gt;Here is a Python function and a test for it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount must be positive&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;insufficient funds&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_withdraw&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That test gives you 47% line coverage. It gives you a 9.5% mutation kill score.&lt;/p&gt;

&lt;p&gt;The harness generates 21 small breakages of that module. The suite notices 2 of them.&lt;/p&gt;

&lt;p&gt;That gap is the whole reason I started this project. Line coverage is the default test-quality signal in most of the industry, and it measures whether a line ran. It does not measure whether anything would have complained if the line were wrong. AI-generated tests are unusually good at producing that shape: high coverage, low detection.&lt;/p&gt;

&lt;p&gt;Mutation testing measures the real thing. You break the code in small ways and check whether the tests notice.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;  def withdraw(balance, amount):
&lt;span class="gd"&gt;-     if amount &amp;lt;= 0:
&lt;/span&gt;&lt;span class="gi"&gt;+     if amount &amp;lt; 0:
&lt;/span&gt;          raise ValueError("amount must be positive")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If no test fails, that is a bug your suite cannot detect. It has been sitting there the whole time.&lt;/p&gt;

&lt;p&gt;Mutation testing never went mainstream, and I think the reason is simple. It hands you a wall of surviving mutants and no path to fixing any of them. It tells you that you have a problem and then leaves.&lt;/p&gt;

&lt;p&gt;So the idea was an agent that closes the loop. Find the survivors. Write tests that kill them. Gate each generated test on a hard criterion: keep it only if it passes on clean code and fails on the mutant. Ground truth is a subprocess exit code. No model judges any outcome.&lt;/p&gt;

&lt;p&gt;I built it over about 30 hours for the micro1 Frontier Engineering Challenge, which had around 7,800 registrants.&lt;/p&gt;

&lt;p&gt;The tool works, sort of. It is incomplete and I will get to the numbers. But that is not the interesting part of the weekend.&lt;/p&gt;

&lt;p&gt;The interesting part is that my measuring instrument kept lying to me, and it lied in a consistent direction.&lt;/p&gt;

&lt;h2&gt;
  
  
  The finding that broke my own premise
&lt;/h2&gt;

&lt;p&gt;Before I ran a single agent call, I ran the harness across 12 widely-used, well-maintained Python libraries: cachetools, validators, natsort, dictdiffer, toolz, voluptuous, python-slugify, python-dotenv, shortuuid, boltons, aiofiles, tenacity.&lt;/p&gt;

&lt;p&gt;455 mutants generated. 133 survived the existing test suites.&lt;/p&gt;

&lt;p&gt;Then I checked something I had assumed I would not need to check. Of those 133 survivors, how many sit on a line the tests actually execute?&lt;/p&gt;

&lt;p&gt;53.&lt;/p&gt;

&lt;p&gt;The rest were never run at all. Not weakly tested. Not vacuously tested. Untested.&lt;/p&gt;

&lt;p&gt;I suspected my test commands were scoped too narrowly, so I widened them per target, between 6 and 40 times more test code. If the "executes but does not assert" category was real and I was just missing it, that number should climb.&lt;/p&gt;

&lt;p&gt;It went from 54 to 53. Down.&lt;/p&gt;

&lt;p&gt;And where widening changed anything, it converted unreachable mutations directly into kills. It did not move them into the middle category. It skipped it.&lt;/p&gt;

&lt;p&gt;So in mature, human-written Python, the vacuous test failure mode is rare. Where these suites fail, they fail by not running the code at all.&lt;/p&gt;

&lt;p&gt;The story I had absorbed about tests that execute everything and assert nothing is a story about AI-generated tests. It is not a story about human ones. I had to reframe the project before I had built the main part of it.&lt;/p&gt;

&lt;p&gt;That was the first sign that what I was actually building was a measuring instrument, and that I had not been treating it like one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Eight bugs in the instrument
&lt;/h2&gt;

&lt;p&gt;Every one of these would have produced a confident, wrong, publishable number.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Editable installs made mutations invisible.&lt;/strong&gt; &lt;code&gt;pip install -e&lt;/code&gt; on src-layout packages resolves imports back to the original checkout. My mutations were written to a temp copy, so they never executed. Three targets silently scored 0.000. That would have read as "the agent fails on src-layout packages," which is a finding. It is just not a true one.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Concurrency corrupted one target.&lt;/strong&gt; Running mutants in parallel gave me three different survivor sets across four runs, on the one target doing real async I/O. I had already drafted a result of "0.27 to 0.77" off that. It was noise. Note which way it pointed: spurious failures get counted as kills, and kills are the number every arm is trying to increase.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A file picker chose the wrong test file.&lt;/strong&gt; On the hardest target. Which means the model would have been shown irrelevant context in exactly the place where context mattered most.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A classifier was about to run on the wrong unit.&lt;/strong&gt; It classified batches, not individual tests. One strong test in a batch of 69 would have marked all 69 as strong.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A reconstruction step dropped shared imports.&lt;/strong&gt; This manufactured test failures that were not real failures.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;An extractor only scanned top-level functions.&lt;/strong&gt; So a perfectly valid &lt;code&gt;unittest.TestCase&lt;/code&gt; response got discarded as "no test found." Worse, the agent's retry loop then received a harness error instead of real pytest output. That quietly disabled the exact mechanism I was trying to measure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;self.assertEqual(...)&lt;/code&gt; was classified as "no assertion."&lt;/strong&gt; This one would have manufactured precisely the finding I was hypothesising. It would have handed me my own conclusion.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;A pre-registered metric was not computable&lt;/strong&gt; on dunder-dispatched code like &lt;code&gt;__call__&lt;/code&gt; and &lt;code&gt;__or__&lt;/code&gt;. It read as a real near-zero rate rather than as undefined.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The two things they had in common
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;They all pointed the same way.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every single one of those eight would have made my result look better, cleaner, or more publishable. Not one of them would have made the agent look worse than it was.&lt;/p&gt;

&lt;p&gt;I do not think that is a coincidence, and I do not think it is a conspiracy either. It is attention. When a number disappoints you, you go looking for the reason. When a number pleases you, you write it up. So the measurement bugs that survive all the way to publication are disproportionately the ones that helped you.&lt;/p&gt;

&lt;p&gt;That is a selection effect operating on your own debugging, and you cannot fix it by being careful. Careful people are exactly as motivated to stop investigating when the number looks good.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;None of them was found by reading code.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every one was caught by running a check whose outcome I had predicted in advance, and getting the wrong answer.&lt;/p&gt;

&lt;p&gt;The clearest case was bug 5. My prediction was: remove this one known-bad test and the suite goes green. It did not go green. That contradiction is the only reason I found the dropped-imports bug before I trusted the numbers it was feeding me.&lt;/p&gt;

&lt;p&gt;I would not have found it by rereading the function. I had already read the function.&lt;/p&gt;

&lt;h2&gt;
  
  
  The results, with the caveats attached
&lt;/h2&gt;

&lt;p&gt;Three arms, same model, same token ceiling.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Arm&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;Mutants killed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;A&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;One prompt: "write as many tests as warranted." The brief's specified baseline.&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;B&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;One test per call, same call count as the agent. No mutation hint, no gate, no retry.&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;C&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The agent: mutation diff in context, execution gate, one retry with real pytest output fed back.&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;On the 15 mutants the agent covered, B killed 1 and C killed 9. Keep rate was 60%, so the gate was genuinely filtering rather than rubber-stamping. Nine retries fired and three succeeded.&lt;/p&gt;

&lt;p&gt;Now the parts that matter just as much.&lt;/p&gt;

&lt;p&gt;The agent ran on 2 of 10 targets. The API budget ran out mid-run. I did not swap in a substitute model to finish the sweep, because then the comparison would not be a comparison.&lt;/p&gt;

&lt;p&gt;Those two targets are the ones where the baseline performed worst. That is not a random sample, and I have no way to argue it is representative.&lt;/p&gt;

&lt;p&gt;All 9 kills were on the two cheapest mutation types. There was zero cross-function transfer. Seven of the nine kept tests kill exactly the one mutation they were written for, and nothing else. That is a real limitation, not a rounding error.&lt;/p&gt;

&lt;h2&gt;
  
  
  One result that inverted my hypothesis
&lt;/h2&gt;

&lt;p&gt;I had pre-registered a prediction that gate-passing tests would mostly be vacuous. Bare existence checks. Tests with no assertion that "kill" a mutant by crashing rather than by detecting anything.&lt;/p&gt;

&lt;p&gt;That is not what happened. The &lt;code&gt;none&lt;/code&gt; category was empty. Eight of the nine kills were real assertion failures.&lt;/p&gt;

&lt;p&gt;And of the six discarded drafts, zero failed on clean code. All six were valid, passing tests that simply did not detect the bug.&lt;/p&gt;

&lt;p&gt;So the gate was not catching broken tests. It was catching working tests that miss. That is a more interesting failure mode than the one I predicted, and I only know it because the prediction was written down first and was wrong in a specific way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The determinism check that quarantined my own target
&lt;/h2&gt;

&lt;p&gt;Three hours before the deadline I did a clean-clone reproduction run to verify the reproducibility claim.&lt;/p&gt;

&lt;p&gt;The determinism check runs each target three times serially and requires the survivor sets to be byte-identical. Eleven of twelve reproduced exactly. The twelfth varied.&lt;/p&gt;

&lt;p&gt;I reported it in the README instead of fixing it. A check that has never caught anything is indistinguishable from a check that cannot catch anything, and the first thing mine ever caught was one of my own targets. Removing that from the record would have made the project look better and the instrument look worse.&lt;/p&gt;

&lt;p&gt;I missed the submission by 11 minutes.&lt;/p&gt;

&lt;p&gt;That is annoying in a way I do not want to dress up. But the reproduction run is what found the twelfth target, and running it is the reason I trust the other eleven.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would tell you to take from this
&lt;/h2&gt;

&lt;p&gt;Before you measure an agent, write down what your instrument would look like if it were lying to you. Then build the check that catches exactly that.&lt;/p&gt;

&lt;p&gt;And write down which direction each possible lie would push your result. That second list is the important one, because it tells you which checks you will be least motivated to run.&lt;/p&gt;

&lt;p&gt;The repo is private while I finish the write-up. If you build evaluations for agents and you have hit this, I would like to compare notes, particularly on catching measurement bias before it reaches a number you have already started believing.&lt;/p&gt;

</description>
      <category>testing</category>
      <category>ai</category>
      <category>python</category>
      <category>showdev</category>
    </item>
    <item>
      <title>5,900 Engineers Just Registered for a Hackathon Where Using AI Is the Point. Here's How It Will Actually Be Judged.</title>
      <dc:creator>Marvin Okafor</dc:creator>
      <pubDate>Fri, 28 Aug 2026 11:16:11 +0000</pubDate>
      <link>https://dev.to/marvinoka4/5900-engineers-just-registered-for-a-hackathon-where-using-ai-is-the-point-heres-how-it-will-1bdd</link>
      <guid>https://dev.to/marvinoka4/5900-engineers-just-registered-for-a-hackathon-where-using-ai-is-the-point-heres-how-it-will-1bdd</guid>
      <description>&lt;p&gt;Most hackathons treat coding agents as something between a crutch and cheating. micro1's Frontier Engineering Challenge, which kicks off today, inverts that entirely: you're &lt;em&gt;expected&lt;/em&gt; to use coding agents. The competition isn't about whether you can generate code. It's about whether you can generate code that survives scrutiny.&lt;/p&gt;

&lt;p&gt;That's a fundamentally different game, and judging by how most engineers approach AI-assisted work, a lot of the field is about to optimise for the wrong thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The details
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;What:&lt;/strong&gt; micro1 Frontier Engineering Challenge 2026 - &lt;cite&gt;a free, global, online competition, run as a three-day sprint where you use coding agents to tackle a real-world software engineering problem&lt;/cite&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When:&lt;/strong&gt; &lt;cite&gt;August 28–31, 2026. The full challenge statement is released at kickoff - August 28 at 15:00 UTC&lt;/cite&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Format:&lt;/strong&gt; Online, individual (team size 1), free&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Registrations so far:&lt;/strong&gt; ~5,900&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why it matters beyond the prize:&lt;/strong&gt; micro1 has indicated that top-performing participants get considered for paid opportunities with them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The problem statement is deliberately withheld until kickoff, so &lt;cite&gt;nobody gets to pre-build&lt;/cite&gt;. Everyone starts cold.&lt;/p&gt;

&lt;h2&gt;
  
  
  The line in the announcement that tells you everything
&lt;/h2&gt;

&lt;p&gt;Buried in the challenge description is the sentence that should reframe your entire strategy: &lt;cite&gt;AI can produce convincing code in seconds - real engineering begins when convincing is not enough: incomplete requirements, hidden dependencies, difficult edge cases, failure modes, and decisions that require technical judgment.&lt;/cite&gt;&lt;/p&gt;

&lt;p&gt;And the deliverable: &lt;cite&gt;a solution that is correct, reproducible, testable and clearly explained.&lt;/cite&gt;&lt;/p&gt;

&lt;p&gt;Read those four words again - &lt;strong&gt;correct, reproducible, testable, explained&lt;/strong&gt;. Not "impressive." Not "feature-complete." Not "shipped fastest." If you've ever built or graded an evaluation rubric, you recognise immediately what that list is: it's a rubric where &lt;em&gt;three of the four criteria have nothing to do with whether your code runs&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where I think most of the field will lose points
&lt;/h2&gt;

&lt;p&gt;I evaluate agentic AI coding outputs against structured rubrics professionally - rubric construction, adversarial prompt design, deciding which checks can be programmatic and which need human judgment. So I'm reading this challenge less as "what should I build" and more as "where does this rubric bite." My honest read:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Reproducibility is the silent killer.&lt;/strong&gt; "It works on my machine after four hours of undocumented agent conversation" is not reproducible. If a judge can't clone your repo and get the same result, correctness is unverifiable - and unverifiable correctness scores as zero, not as partial credit. Pin your dependencies. Commit your lockfile. Containerize. Make the setup a single command.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. "Testable" doesn't mean "has tests."&lt;/strong&gt; It means the tests actually prove the thing that matters. A test suite that only covers the happy path proves your agent could write a happy path. The edge cases and failure modes the challenge explicitly calls out - those need tests that would &lt;em&gt;fail&lt;/em&gt; if the behaviour were wrong. If deleting your error-handling doesn't break any test, you don't have error-handling coverage; you have decoration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Agents are confidently wrong about failure, not about syntax.&lt;/strong&gt; This is the pattern I keep seeing in evaluation work: the generated code is syntactically perfect and semantically wrong about what happens when things break. Retries, timeouts, partial writes, duplicate messages, concurrent access. Given the challenge explicitly names failure modes as part of the frontier, this is almost certainly where the separation happens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. "Clearly explained" is a scored deliverable, not a README afterthought.&lt;/strong&gt; When ambiguity is baked into the problem statement - and the announcement promises incomplete requirements - the judges cannot read your mind about which interpretation you chose. Your write-up needs to name the ambiguity, state the interpretation you picked, and justify it. An engineer who documents "the spec didn't define whether delivery is at-least-once or exactly-once; I assumed at-least-once and made the consumer idempotent, here's why" is demonstrating exactly the technical judgment being tested. An engineer who silently picks one and says nothing looks identical to an engineer who never noticed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Time will go where you don't expect.&lt;/strong&gt; With agents, generating a working first draft is the fast part. Verification, reproducibility, and documentation are where three days actually go. Budget accordingly - a working solution with no test suite and no write-up will lose to a slightly narrower solution that's fully verified and clearly reasoned.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I'd structure the three days
&lt;/h2&gt;

&lt;p&gt;Rough plan, adjust to the actual problem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Day 1 - Specify before you generate.&lt;/strong&gt; Read the problem twice. Write down every ambiguous term &lt;em&gt;before&lt;/em&gt; you touch an agent, because every ambiguity is a decision you'll otherwise make accidentally. Decide what "correct" means, concretely, in a form you could test. Set up the reproducible environment (container, lockfile, one-command setup) first, not last.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Day 2 - Generate, then attack your own output.&lt;/strong&gt; Use agents aggressively for the implementation. Then switch hats: try to break it. Inject the failure modes. Write tests that would fail if the behaviour were wrong. Every defect you find yourself is one a judge doesn't find for you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Day 3 - Write the explanation as if the reader is sceptical.&lt;/strong&gt; Architecture, edge cases considered and rejected, ambiguities and your resolutions, known limitations. Stating a limitation honestly reads as judgment. Hiding one reads as an oversight when someone finds it - and someone will.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The thing I'd most want to internalise: &lt;strong&gt;stating what you deliberately did not do, and why, is a strength.&lt;/strong&gt; Rubrics reward demonstrated judgment. Scope honesty is judgment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this format is a signal about where engineering is going
&lt;/h2&gt;

&lt;p&gt;There's a real argument that this is what technical hiring looks like in a couple of years. Not "can you invert a binary tree without autocomplete," but "given agents that generate plausible code instantly, can you specify, verify, and defend a solution?" That's a senior-engineering skill set, and it's notably &lt;em&gt;not&lt;/em&gt; the skill set that LeetCode grinding builds.&lt;/p&gt;

&lt;p&gt;Registration and the full brief are on HackerEarth - the problem statement drops at 15:00 UTC today. I'm going in, and I'll write up what I learn regardless of how I place, including anything I get wrong in the read above.&lt;/p&gt;

&lt;p&gt;If you're competing too, say so in the comments - I'd like to compare approaches afterwards, especially on how people handled the ambiguity-documentation piece.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I write about production debugging, performance work, and building evaluation environments for AI systems. Previous posts in this series cover deterministic RL environments for cloud infrastructure and what months of grading agentic code taught me about where models actually fail.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>hackathon</category>
      <category>ai</category>
      <category>devops</category>
      <category>career</category>
    </item>
    <item>
      <title>I've Spent Months Grading AI Agents' Code for a Living. Here's the Pattern Nobody's Talking About</title>
      <dc:creator>Marvin Okafor</dc:creator>
      <pubDate>Thu, 06 Aug 2026 18:20:52 +0000</pubDate>
      <link>https://dev.to/marvinoka4/ive-spent-months-grading-ai-agents-code-for-a-living-heres-the-pattern-nobodys-talking-about-34bf</link>
      <guid>https://dev.to/marvinoka4/ive-spent-months-grading-ai-agents-code-for-a-living-heres-the-pattern-nobodys-talking-about-34bf</guid>
      <description>&lt;p&gt;Everyone's talking about agentic AI shipping production code. Nobody's talking about what happens when you actually sit down and grade thousands of lines of it against a rubric, line by line, for months.&lt;/p&gt;

&lt;p&gt;I have. And the failure pattern that shows up over and over isn't the one Twitter/X is arguing about.&lt;/p&gt;

&lt;h2&gt;
  
  
  The job title that didn't exist two years ago
&lt;/h2&gt;

&lt;p&gt;"AI evaluator." "AI trainer." "Expert contributor to frontier model training data." None of these existed as job titles when I started my career. Now they're where a chunk of the most interesting engineering signal in the industry is actually happening — quietly, behind NDAs, far from the demo videos.&lt;/p&gt;

&lt;p&gt;Here's what the job actually is: agentic coding outputs land on your desk, and you grade them against a structured rubric — correctness, instruction adherence, quality, edge-case handling. You design adversarial prompts to find where the model's reasoning breaks. You decide which checks can be programmatic and deterministic, and which genuinely need a human who's shipped production systems to make the call. This is &lt;strong&gt;RL environment design&lt;/strong&gt; and &lt;strong&gt;LLMOps&lt;/strong&gt; in its rawest form, and it's a completely different skill from "prompt engineer" or "ML researcher." It's closer to being a QA lead for a junior engineer who never sleeps, never gets embarrassed, and will confidently ship the wrong answer with perfect syntax.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pattern: agents are great at code, bad at consequences
&lt;/h2&gt;

&lt;p&gt;Here's the uncomfortable part. The failure mode people are loudest about — hallucinated APIs, made-up library functions — is the &lt;em&gt;easy&lt;/em&gt; failure mode. It's loud, it's obvious, and any decent test suite catches it in seconds.&lt;/p&gt;

&lt;p&gt;The failure mode that actually matters, the one that slips past a surface read and even past a naive test suite, looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The code is syntactically perfect and semantically wrong about failure.&lt;/strong&gt; It handles the happy path beautifully and quietly assumes the retry, the timeout, the partial write, the duplicate message never happens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It optimises for the metric, not the intent&lt;/strong&gt; — the agentic-AI version of Goodhart's Law. Give a model a rubric that checks "does the deploy succeed," and you'll occasionally get a solution that technically satisfies the check while doing something no engineer would sign off on. Evaluators call this &lt;strong&gt;reward hacking&lt;/strong&gt;, and it's a far more common failure than outright hallucination once you're grading real-world infra tasks instead of leetcode.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's confidently wrong about IAM, concurrency, and distributed state&lt;/strong&gt; — exactly the areas where production engineering experience matters most and where a rubric written by someone who's never operated a real system will miss the defect entirely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this is a knock on the models. It's a knock on how we evaluate them. You cannot catch consequence-blindness with a rubric written by someone who has never had a database silently corrupt state under a race condition at 2am. This is the actual bottleneck in scaling agentic AI into production-grade infrastructure work: not model capability, &lt;strong&gt;evaluation quality&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why "vibe coding" breaks down at the infra layer
&lt;/h2&gt;

&lt;p&gt;"Vibe coding" — accepting AI-generated code because it &lt;em&gt;looks&lt;/em&gt; right and the demo works — is fine for a prototype. It is not fine for anything touching IAM policies, message queues, durable storage, or disaster recovery. The gap between "looks right" and "is right" is exactly the gap that &lt;strong&gt;golden reference solutions&lt;/strong&gt; and &lt;strong&gt;deterministic validation tests&lt;/strong&gt; exist to close — the same discipline I wrote about in my last post on building RL environments for cloud infrastructure evaluation.&lt;/p&gt;

&lt;p&gt;The uncomfortable truth for the "AI writes all our code now" crowd: the more production-grade the system, the more the bottleneck shifts from &lt;em&gt;generating&lt;/em&gt; the code to &lt;em&gt;specifying and verifying&lt;/em&gt; it. That's a systems-engineering problem, not a model-scaling problem. It's also, not coincidentally, exactly what senior backend engineers have spent their careers getting good at — writing test suites against real databases instead of mocks, root-causing defects that hide three layers deep, documenting edge cases precisely enough that someone else can reproduce the reasoning. That skill set didn't get less valuable when agents showed up. It became the thing standing between "the demo worked" and "it survived contact with production."&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'm building next
&lt;/h2&gt;

&lt;p&gt;I'm turning this into a real project instead of just a hot take: a lightweight harness for stress-testing AI-agent-generated infrastructure code against realistic, injected failure conditions — retries, partial outages, IAM misconfigurations, the exact defect classes I've been describing above — with &lt;strong&gt;deterministic pass/fail checks&lt;/strong&gt; instead of vibes. Think chaos engineering meets AI evals: inject one fault at a time, assert invariants instead of traces, and see whether an agent's "working" solution is actually working or just golden-path lucky.&lt;/p&gt;

&lt;p&gt;It'll live on my portfolio and GitHub as I build it in the open — seed scenarios, the fault-injection harness, and a write-up of what breaks and why. If you're working on anything adjacent (RL environments, AI evals, chaos engineering, or you've just been burned by AI-generated infra code in production), I want to hear about it — drop it in the comments or find me on GitHub.&lt;/p&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;Agentic AI isn't going to be stopped by a model that can't write a for-loop. It's going to be shaped by whether the industry gets serious about &lt;strong&gt;evaluation infrastructure&lt;/strong&gt; — golden solutions, deterministic tests, adversarial failure scenarios — as fast as it's getting excited about generation. That's the unglamorous, unsexy, extremely fundable problem hiding behind every "AI wrote our whole backend" headline.&lt;/p&gt;

&lt;p&gt;If you've seen this pattern too — agents that ace the demo and fail the disaster-recovery drill — I'd genuinely like to compare notes.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This is the fifth in a series on production engineering, debugging, and building evaluation environments for AI systems. Follow for the harness build-in-public over the coming weeks.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llmops</category>
      <category>agenticai</category>
      <category>careerdev</category>
    </item>
    <item>
      <title>Building Deterministic RL Environments for Cloud Infrastructure Evaluation: What Actually Transfers From Production Engineering</title>
      <dc:creator>Marvin Okafor</dc:creator>
      <pubDate>Thu, 06 Aug 2026 18:16:20 +0000</pubDate>
      <link>https://dev.to/marvinoka4/building-deterministic-rl-environments-for-cloud-infrastructure-evaluation-what-actually-transfers-52jm</link>
      <guid>https://dev.to/marvinoka4/building-deterministic-rl-environments-for-cloud-infrastructure-evaluation-what-actually-transfers-52jm</guid>
      <description>&lt;p&gt;AI models are increasingly being asked to design, deploy, secure, and recover production-grade infrastructure — not just write functions that pass a unit test. That shift changes what a training environment has to be. It's no longer enough to check that output "looks right." You need a &lt;strong&gt;golden reference solution&lt;/strong&gt;, a &lt;strong&gt;deterministic validation suite&lt;/strong&gt;, and a set of &lt;strong&gt;intentionally broken variants&lt;/strong&gt; that probe exactly where a model's reasoning breaks down under failure.&lt;/p&gt;

&lt;p&gt;I've spent the last several months on the other side of this problem — evaluating agentic coding outputs against structured rubrics, designing programmatic verification checks, and writing up edge cases that rubric authors hadn't considered. Before that, I spent seven years building and debugging the kind of systems these environments are meant to simulate: multi-tenant SaaS platforms with row-level security, AWS infrastructure serving high-traffic e-commerce, and data pipelines processing tens of thousands of concurrent requests. This post is about where those two things meet — what it actually takes to build an infrastructure RL environment that's reproducible, fair to evaluate, and hard to game.&lt;/p&gt;

&lt;h2&gt;
  
  
  A golden solution is only as good as its ambiguity budget
&lt;/h2&gt;

&lt;p&gt;The first mistake in building any evaluation environment is under-specifying the scenario and over-specifying the solution. If the task says "deploy a fault-tolerant queue consumer" without pinning down delivery semantics, retry policy, and what "fault-tolerant" means operationally, you'll end up with a golden solution that's just &lt;em&gt;one&lt;/em&gt; valid interpretation among several — and you'll penalize a model for a decision the spec never actually made.&lt;/p&gt;

&lt;p&gt;This is the same discipline as writing rubrics for coding evaluations: every ambiguous term is a future dispute. In practice that means, before writing a single line of infrastructure code, defining:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The exact failure modes in scope (node loss, network partition, message duplication, clock skew)&lt;/li&gt;
&lt;li&gt;The invariants that must hold regardless of implementation (at-least-once vs exactly-once delivery, idempotency guarantees, RTO/RPO targets)&lt;/li&gt;
&lt;li&gt;What counts as "recovered" — not just "the service is up," but that state is consistent&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Deterministic validation means designing against non-determinism
&lt;/h2&gt;

&lt;p&gt;Distributed systems are inherently non-deterministic — that's exactly what makes them hard to evaluate. A validation suite that works by re-running the same sequence of API calls and diffing output will produce flaky, unfair results the moment retries, timeouts, or eventual consistency are involved.&lt;/p&gt;

&lt;p&gt;The pattern that's worked for me, most recently writing a security test suite that validates row-level-security policies against a real Postgres instance rather than mocks, is to validate &lt;strong&gt;invariants&lt;/strong&gt;, not &lt;strong&gt;traces&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Anti-pattern: asserting on the exact sequence of events
&lt;/span&gt;&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;consumer_started&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message_received&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message_processed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ack_sent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Better: assert the invariant the system must uphold,
# regardless of retries, ordering, or timing
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_no_duplicate_side_effects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inject_fault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;redeliver_message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run_until_settled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;side_effect_count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;charge_customer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;final_state_is_consistent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Testing against a real, disposable instance of the actual dependency — a real queue, a real Postgres, a real IAM policy engine — rather than a mock catches the class of bug that mocks are structurally blind to: the ones where the &lt;em&gt;contract&lt;/em&gt; you assumed doesn't match the &lt;em&gt;behaviour&lt;/em&gt; you get. I've root-caused production bugs (a minor dependency version bump silently collapsing TypeScript types to &lt;code&gt;never&lt;/code&gt;, an OAuth token-refresh edge case that only reproduced under real API rate limits) that a mocked test suite would have sailed straight past. The same principle applies at the infrastructure layer, just with higher stakes per failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Defective variants need to fail for the &lt;em&gt;right&lt;/em&gt; reason
&lt;/h2&gt;

&lt;p&gt;The point of an intentionally broken variant isn't just "does the model notice something is wrong" — it's "does the model correctly diagnose &lt;em&gt;why&lt;/em&gt;." A variant with a misconfigured IAM policy that happens to also have a network misconfiguration will teach a model to pattern-match on the wrong signal.&lt;/p&gt;

&lt;p&gt;Building these well means treating each defect as a single, isolated hypothesis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One fault per variant.&lt;/strong&gt; Resist the urge to combine a broken retry policy and an under-provisioned autoscaling group into one scenario "for efficiency." You'll never know which one the model actually reasoned about.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fail loud enough to be observable, quiet enough to require diagnosis.&lt;/strong&gt; A defect that immediately crashes the deploy is a smoke test, not an evaluation. A defect that silently corrupts data under specific timing conditions is where reasoning gets tested — but it has to be &lt;em&gt;reliably&lt;/em&gt; reproducible, or you're evaluating luck.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document the intended diagnosis path.&lt;/strong&gt; If you can't write down, in advance, the sequence of observability signals (logs, metrics, traces) that should lead a correct reasoner to the root cause, the variant isn't ready yet.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where this comes from, concretely
&lt;/h2&gt;

&lt;p&gt;None of this is theoretical for me. A few data points from production work that map directly onto this kind of environment design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wrote and maintain a 14-test security suite validating row-level-security policies against a real Postgres database — the reproducible-environment-over-mocks principle, applied.&lt;/li&gt;
&lt;li&gt;Root-caused a silent dependency-resolution failure where a minor version bump collapsed TypeScript types to &lt;code&gt;never&lt;/code&gt; across a monorepo — the kind of defect class that's genuinely worth encoding as a training scenario, because it's realistic and painful to diagnose.&lt;/li&gt;
&lt;li&gt;Built and operated AWS infrastructure (EC2, S3, Lambda) for a high-traffic e-commerce platform, including the profiling and query-optimisation work behind a 30% latency reduction — direct experience with the observability and performance-diagnosis loop these environments are meant to simulate.&lt;/li&gt;
&lt;li&gt;Currently evaluate agentic coding outputs against structured rubrics professionally, including rubric construction, adversarial prompt design, and selecting which checks are actually programmatically verifiable versus which need human judgment — the exact skill set "golden reference solution + deterministic test" environment design draws on.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The uncomfortable part: most of the work is writing, not coding
&lt;/h2&gt;

&lt;p&gt;The infrastructure code for a good RL environment is often the easy part. The hard part is the documentation — writing down, precisely enough that someone else could reproduce your reasoning, what each scenario is testing, what "correct" means, what edge cases were considered and rejected, and why. That's not a side task. For environments meant to train reasoning about production systems, the documentation &lt;em&gt;is&lt;/em&gt; the specification the golden solution is graded against. Treating it as an afterthought is how you end up with an environment that's internally inconsistent and nobody notices until a model exploits the gap.&lt;/p&gt;

&lt;p&gt;If you're building or evaluating environments in this space, I'd be glad to compare notes — particularly on validating distributed invariants without flaking, and on keeping golden solutions honest about which parts of a spec are actually unambiguous.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>backend</category>
      <category>devops</category>
      <category>testing</category>
    </item>
    <item>
      <title>Postmortem: How a Minor Version Bump Silently Collapsed Our Types to `never`</title>
      <dc:creator>Marvin Okafor</dc:creator>
      <pubDate>Thu, 06 Aug 2026 18:15:45 +0000</pubDate>
      <link>https://dev.to/marvinoka4/postmortem-how-a-minor-version-bump-silently-collapsed-our-types-to-never-485e</link>
      <guid>https://dev.to/marvinoka4/postmortem-how-a-minor-version-bump-silently-collapsed-our-types-to-never-485e</guid>
      <description>&lt;p&gt;Some bugs announce themselves with a stack trace. Others just make your code quietly stop meaning anything. This is about the second kind — a dependency resolution issue in a TypeScript monorepo that didn't throw, didn't fail CI in an obvious way, and took real digging to root-cause, because the symptom looked nothing like the cause.&lt;/p&gt;

&lt;h2&gt;
  
  
  The symptom
&lt;/h2&gt;

&lt;p&gt;We're a Next.js + TypeScript monorepo using npm workspaces, on top of Supabase/Postgres with row-level-security policies. One afternoon, a teammate opened a PR, and the type checker flagged what looked like an unrelated function as having a parameter of type &lt;code&gt;never&lt;/code&gt;. Not &lt;code&gt;unknown&lt;/code&gt;, not &lt;code&gt;any&lt;/code&gt; — &lt;code&gt;never&lt;/code&gt;. That's the type TypeScript uses to say "this code path is unreachable" or "no value can satisfy this type."&lt;/p&gt;

&lt;p&gt;The function in question was very much reachable. It was called constantly, in production, successfully. TypeScript was simply wrong about it — or rather, TypeScript was being correctly told the wrong thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why &lt;code&gt;never&lt;/code&gt; is the worst possible symptom
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;never&lt;/code&gt; is a black hole in the type system. Once a type collapses to &lt;code&gt;never&lt;/code&gt;, everything downstream that touches it also tends to become uninferrable or nonsensical, because there's no value that can inhabit &lt;code&gt;never&lt;/code&gt;. This means the &lt;em&gt;first&lt;/em&gt; place you see an error is rarely anywhere near the actual cause — the type has already been wrong for several hops by the time the checker has no choice but to complain.&lt;/p&gt;

&lt;p&gt;That property makes this class of bug genuinely dangerous to debug by intuition. Staring at the flagged function tells you almost nothing, because the function is innocent. You have to work backwards through the type's provenance instead of forwards from the symptom.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tracing it back
&lt;/h2&gt;

&lt;p&gt;The investigation went roughly like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Confirm it's not a logic bug.&lt;/strong&gt; Runtime behaviour was correct. This ruled out anything in our own function bodies and pointed at the type layer specifically — either our type definitions or something upstream of them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bisect the type, not the code.&lt;/strong&gt; I traced the offending type backwards through each intermediate type alias and generic constraint until I found the layer where it stopped being sane. It turned out to originate from a shared type re-exported from one of our internal workspace packages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check what changed.&lt;/strong&gt; &lt;code&gt;git log&lt;/code&gt; on the lockfile, not the source, is the move here — the source hadn't changed. A transitive dependency had bumped a &lt;em&gt;minor&lt;/em&gt; version, which under semver should have been safe.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reproduce in isolation.&lt;/strong&gt; I pinned every workspace package to the exact versions from before the bump, confirmed the type error disappeared, then bumped dependencies one at a time until it reappeared. This isolated the exact package and version.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Understand the actual mechanism.&lt;/strong&gt; The new minor version had changed an internal conditional type in a way that was backwards-compatible at the &lt;em&gt;value&lt;/em&gt; level but not at the &lt;em&gt;type inference&lt;/em&gt; level for one specific generic usage pattern we relied on. Semver protects you from breaking runtime behaviour; it says nothing about breaking type inference for edge-case generic usage. That's the real lesson here.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The fix, and the more important fix
&lt;/h2&gt;

&lt;p&gt;The immediate fix was a version pin with a comment explaining exactly why, linking to the isolated repro. That's necessary but not sufficient — a pin with no explanation just becomes a mystery for the next person, and eventually someone "cleans it up" and reintroduces the bug.&lt;/p&gt;

&lt;p&gt;The more important fix was writing it up: what the symptom looked like, why it was misleading, the bisection method that found it, and the underlying mechanism (type-level semver violations in transitive dependencies). That doc is what turns a three-hour debugging session into a five-minute fix the next time a teammate hits something that smells similar.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd generalise from this
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;When a type error implicates innocent code, suspect provenance, not logic.&lt;/strong&gt; &lt;code&gt;never&lt;/code&gt; and its cousins are usually downstream symptoms of an upstream problem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bisect the dependency graph, not just your own commits.&lt;/strong&gt; Runtime-correct, type-broken changes are invisible to normal "did my code change" instincts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Semver is a promise about behaviour, not about type inference.&lt;/strong&gt; Especially in libraries that lean on conditional or mapped types, a "minor" bump can break inference for edge-case usages that the maintainers never tested against.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The write-up is part of the fix.&lt;/strong&gt; A pinned version with no documented reasoning is technical debt with a delay timer on it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Debugging this kind of thing is oddly satisfying once you see the shape of it — the bug isn't in the obvious place; it's in the second-order effects of a decision made three layers away. If you've hit something similar in a large TypeScript monorepo, I'd be curious to compare notes on tooling for catching type-level regressions from dependency bumps before they reach a PR.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>webdev</category>
      <category>debugging</category>
    </item>
    <item>
      <title>Cutting Latency by 30% on a High-Traffic E-Commerce Platform: A Profiling-First Approach</title>
      <dc:creator>Marvin Okafor</dc:creator>
      <pubDate>Thu, 06 Aug 2026 18:15:07 +0000</pubDate>
      <link>https://dev.to/marvinoka4/cutting-latency-by-30-on-a-high-traffic-e-commerce-platform-a-profiling-first-approach-e2b</link>
      <guid>https://dev.to/marvinoka4/cutting-latency-by-30-on-a-high-traffic-e-commerce-platform-a-profiling-first-approach-e2b</guid>
      <description>&lt;p&gt;"Make it faster" is one of the least actionable instructions in engineering, right up until you have data telling you exactly where the time is going. Over about two and a half years on a high-traffic e-commerce platform, we reduced platform latency by roughly 30% while maintaining 99.9% uptime during peak trading periods — including the highest-traffic days of the year, when the margin for error is smallest, and the cost of getting it wrong is highest. None of it came from a single dramatic rewrite. It came from a repeatable process, applied consistently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start by refusing to guess
&lt;/h2&gt;

&lt;p&gt;The instinct when something feels slow is to optimise the thing you &lt;em&gt;assume&lt;/em&gt; is slow — usually whatever you last touched, or whatever looks inefficient on a quick read. That instinct is wrong often enough to be actively dangerous, because "optimising" code that wasn't the bottleneck adds complexity and risk for zero latency benefit, and it burns the time you should have spent on the actual bottleneck.&lt;/p&gt;

&lt;p&gt;The fix is boring and non-negotiable: profile first, in an environment that resembles production traffic patterns, before writing a single optimisation. Real bottlenecks are frequently unglamorous — an N+1 query hiding behind an ORM abstraction, a synchronous call to a downstream service that could have been parallelised, a cache that's technically present but missing on the hot path that actually matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the 30% actually came from
&lt;/h2&gt;

&lt;p&gt;Roughly, the wins broke down into three categories:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Query optimisation.&lt;/strong&gt; The single highest-leverage category. Several code paths were making sequential database round-trips with no data dependencies between them — classic N+1 patterns introduced incrementally as features were added over time, none individually alarming, collectively expensive. Batching these, and in a few cases denormalising specific hot-path reads, produced the largest single latency improvements we measured.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Targeted refactoring of performance-critical paths.&lt;/strong&gt; Not a rewrite — a refactor scoped specifically to the paths the profiler flagged. This mattered for maintainability as much as speed: refactoring only what the data justified meant the team could reason about &lt;em&gt;why&lt;/em&gt; each change existed, instead of inheriting a large diff whose performance rationale had to be taken on faith.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Infrastructure-level tuning.&lt;/strong&gt; Some latency wasn't in application code at all. Right-sizing EC2 instances and Lambda configurations for actual observed load, rather than defaults inherited from an earlier stage of the business, closed gaps that no amount of query optimisation would have touched.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part that's easy to skip: measuring in production, safely
&lt;/h2&gt;

&lt;p&gt;A profiler on a laptop tells you about your laptop. Production traffic has a shape — concurrency patterns, cache warmth, data skew — that's genuinely hard to fake in staging. The way to close that gap without risking the platform is incremental rollout with real metrics at every step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Ship the change behind a flag or to a small traffic percentage
2. Compare p50/p95/p99 latency against the control group, not just the mean
3. Watch error rate and downstream load, not just the metric you're optimising
4. Roll forward only when the data says so — not the calendar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The p95/p99 discipline matters specifically because averages hide the experience of your worst-off users, and in e-commerce, the worst-off users during peak trading are disproportionately the ones checking out at the exact moment load is highest — which is to say, the moment you can least afford to be wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automation as a latency and reliability strategy
&lt;/h2&gt;

&lt;p&gt;Alongside the latency work, we built internal automation that cut manual data processing by 80%. That's not directly a latency number, but it's related: manual processes are a hidden source of both delay and error, and every manual step you remove is one less place where a human under time pressure introduces a mistake during exactly the high-traffic periods when mistakes are costliest. Reliability and performance work end up reinforcing each other more than people expect.&lt;/p&gt;

&lt;h2&gt;
  
  
  What held up across the whole effort
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Profile before you touch anything.&lt;/strong&gt; Every optimisation that didn't start here either did nothing measurable or made something else worse.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimize what the data flags, not what looks inefficient.&lt;/strong&gt; These are not the same list, and the gap between them is where wasted effort lives.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Measure tail latency, not averages.&lt;/strong&gt; Peak-trading experience is a p99 problem, not a p50 problem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ship incrementally, with rollback as a real option, not a theoretical one.&lt;/strong&gt; 99.9% uptime through peak periods isn't compatible with big-bang deploys.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The unglamorous truth is that most of the 30% came from patient, boring, well-measured work — not a single clever trick. That's usually how sustainable performance work goes, and it's the part that's easy to leave out of the story.&lt;/p&gt;

</description>
      <category>performance</category>
      <category>postgres</category>
      <category>aws</category>
    </item>
    <item>
      <title>Why We Test Row-Level Security Against a Real Postgres Database, Not Mocks</title>
      <dc:creator>Marvin Okafor</dc:creator>
      <pubDate>Thu, 06 Aug 2026 18:14:21 +0000</pubDate>
      <link>https://dev.to/marvinoka4/why-we-test-row-level-security-against-a-real-postgres-database-not-mocks-kg2</link>
      <guid>https://dev.to/marvinoka4/why-we-test-row-level-security-against-a-real-postgres-database-not-mocks-kg2</guid>
      <description>&lt;p&gt;Row-level security is one of the few places in a backend where I think mocking your database is close to indefensible. RLS policies aren't application logic you wrote and understand the shape of — they're rules enforced by the database engine itself, evaluated per-row, per-query, based on session context. A mock can't tell you whether a real policy actually does what you think it does, because a mock doesn't run the policy. It runs your assumption about the policy.&lt;/p&gt;

&lt;p&gt;When we built the auth and data-access layer for a multi-tenant healthcare platform — Supabase/Postgres underneath a Next.js/TypeScript monorepo, with magic-link/OTP authentication — this wasn't a theoretical concern. Getting row-level security wrong in a healthcare context isn't a bug, it's a data breach. So the test suite (14 tests, and growing) runs against a real, disposable Postgres instance, not a mock, and that decision is the single highest-leverage testing choice in the codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a mock actually can't catch
&lt;/h2&gt;

&lt;p&gt;Mocking the database for RLS tests usually means mocking the &lt;em&gt;query layer&lt;/em&gt; — you assert that your application code called the database with the parameters you expected, and you trust that the policy you wrote does the right thing with them. That trust is exactly the thing under test, and a mock structurally cannot verify it, because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Policy interaction effects.&lt;/strong&gt; Postgres RLS policies combine with &lt;code&gt;AND&lt;/code&gt;/&lt;code&gt;OR&lt;/code&gt; depending on how they're defined (permissive vs. restrictive), and with multiple policies on a table, the actual enforced behaviour is a function of all of them together. You cannot reason about this correctly by reading one policy in isolation — you have to run the query.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session context propagation.&lt;/strong&gt; RLS policies typically key off session variables (e.g., the authenticated user's ID via &lt;code&gt;auth.uid()&lt;/code&gt; in Supabase's convention). Whether that context is actually set correctly, at the right point in the connection lifecycle, for the actual role the application connects as, is an integration concern a mock skips entirely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Role and grant subtleties.&lt;/strong&gt; RLS interacts with the underlying &lt;code&gt;GRANT&lt;/code&gt;/role system — a policy can be technically correct and still leak data if the connecting role has table-level privileges that bypass or interact unexpectedly with the policy. This is invisible until you run against the real privilege system.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What the suite actually asserts
&lt;/h2&gt;

&lt;p&gt;The structure that's worked well is to test from the perspective of each role or tenant context that the system supports, asserting both what &lt;em&gt;should&lt;/em&gt; be visible and what should be invisible — the second half is the one people skip, and it's the half that actually matters for security:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Setup: two tenants, each with their own row&lt;/span&gt;
&lt;span class="k"&gt;insert&lt;/span&gt; &lt;span class="k"&gt;into&lt;/span&gt; &lt;span class="n"&gt;records&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;values&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'tenant_a'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'alpha-data'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'tenant_b'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'beta-data'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_tenant_isolation_positive_and_negative&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Positive: tenant A can see its own row
&lt;/span&gt;    &lt;span class="n"&gt;as_tenant_a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect_as&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tenant&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tenant_a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;as_tenant_a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;select * from records&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;row_ids&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="c1"&gt;# Negative: tenant A cannot see tenant B's row, even by direct id lookup
&lt;/span&gt;    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;as_tenant_a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;select * from records where id = 2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;row_ids&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;  &lt;span class="c1"&gt;# not an error — silently filtered, as RLS does
&lt;/span&gt;
    &lt;span class="c1"&gt;# Negative: tenant A cannot write into tenant B's rows
&lt;/span&gt;    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;pytest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;raises&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PolicyViolation&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;as_tenant_a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;update records set payload = &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt; where id = 2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That silent-filtering behaviour in the second case is itself worth calling out: RLS doesn't throw a permission error for a &lt;code&gt;SELECT&lt;/code&gt; that matches no visible rows; it just returns zero rows, indistinguishable from "that row doesn't exist." That's correct and intentional (it avoids leaking existence), but it means a test suite that only checks for "no error" will falsely pass a query that's silently returning the wrong (empty) data for the wrong reason. You have to assert the actual row set, not just the absence of an exception.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making it reproducible, not just correct
&lt;/h2&gt;

&lt;p&gt;A real-database test suite is only as good as its reproducibility. The parts that made this sustainable rather than flaky:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A disposable instance per test run&lt;/strong&gt;, via Docker, seeded fresh each time — not a shared dev database that accumulates state and false confidence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deterministic seed data&lt;/strong&gt; with intentionally adversarial rows (near-boundary tenant IDs, null edge cases) rather than only the happy-path rows a developer would think to add by hand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Migration tooling that runs the same schema and policy definitions the test suite validates against&lt;/strong&gt; — so the tests can't silently drift from what's actually deployed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The trade-off, honestly
&lt;/h2&gt;

&lt;p&gt;Real-database tests are slower than mocks and require more infrastructure (a Docker-managed Postgres in CI, migration and seed tooling to keep it deterministic). That cost is real. But for anything where the correctness property you're testing is enforced &lt;em&gt;by the database itself&lt;/em&gt; rather than by your application code, a faster test that can't actually catch the failure mode isn't a good trade — it's a false sense of coverage. For RLS specifically, given what's at stake when it's wrong, that trade isn't close.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>security</category>
      <category>testing</category>
    </item>
    <item>
      <title>Building the Future of Sustainable Materials: A Developer's Journey with Kiro</title>
      <dc:creator>Marvin Okafor</dc:creator>
      <pubDate>Mon, 15 Sep 2025 16:00:58 +0000</pubDate>
      <link>https://dev.to/marvinoka4/building-the-future-of-sustainable-materials-a-developers-journey-with-kiro-5ecg</link>
      <guid>https://dev.to/marvinoka4/building-the-future-of-sustainable-materials-a-developers-journey-with-kiro-5ecg</guid>
      <description>&lt;p&gt;The fashion industry has a problem. While brands are under increasing pressure to adopt sustainable materials, the process of finding, evaluating, and implementing these alternatives remains frustratingly complex. That's where our latest project comes in: the &lt;strong&gt;Sustainable Materials Platform&lt;/strong&gt; – a comprehensive web application that makes adopting sustainable materials as simple as a few clicks.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge: Bridging Sustainability and Practicality
&lt;/h2&gt;

&lt;p&gt;When we began this project, the landscape was clear: fashion brands wanted to be more sustainable, but they were overwhelmed by complexity. Questions like "Which recycled cotton blend offers the best durability-to-cost ratio?" or "How will EU 2027 regulations affect our material costs?" required hours of research across multiple suppliers, databases, and regulatory documents.&lt;/p&gt;

&lt;p&gt;We needed to build something that could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provide instant access to comprehensive material data&lt;/li&gt;
&lt;li&gt;Forecast costs with regulatory impact modelling&lt;/li&gt;
&lt;li&gt;Offer AI-powered recommendations based on specific requirements&lt;/li&gt;
&lt;li&gt;Present everything through a beautiful, intuitive interface&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Technical Foundation: Modern Stack, Sustainable Focus
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Frontend: React 18 + Tailwind CSS + Framer Motion
&lt;/h3&gt;

&lt;p&gt;We chose React 18 for its performance and ecosystem, but the real magic happens in the UI layer. Using Tailwind CSS, we created a glass morphism design system that feels both modern and trustworthy – crucial for enterprise adoption.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Our hero header showcases the platform's environmental focus&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;relative overflow-hidden&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;absolute inset-0 bg-gradient-to-r from-primary-600 via-primary-700 to-green-600&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;motion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;
    &lt;span class="nx"&gt;initial&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="nx"&gt;animate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="nx"&gt;transition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text-5xl md:text-6xl font-bold text-white&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;Sustainable&lt;/span&gt; &lt;span class="nx"&gt;Materials&lt;/span&gt; &lt;span class="nx"&gt;Platform&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/motion.div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/header&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Framer Motion adds the smooth animations that make the platform feel alive. Every interaction – from material card flips to chart transitions – reinforces the platform's focus on seamless user experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Backend: Flask + AI-Powered Matching
&lt;/h3&gt;

&lt;p&gt;The backend is intentionally lightweight but powerful. We built a Flask API that serves realistic material data and implements rule-based AI for material matching:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Our AI matching algorithm considers multiple factors
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_sustainability_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;material&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;recyclability&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;material&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;recyclability_score&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;transparency&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;material&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;transparency_score&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;social&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;material&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;social_score&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Weighted composite score
&lt;/span&gt;    &lt;span class="nf"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;recyclability&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.4&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;transparency&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;social&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Features That Make a Difference
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Material Database with LCA Benchmarking
&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.amazonaws.com%2Fuploads%2Farticles%2Fi2x32bee3qnph5a1kxry.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%2Fi2x32bee3qnph5a1kxry.png" alt="Material Database"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our database includes 10 carefully researched materials with real-world data. Each material card shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cost per kg with MOQ considerations&lt;/li&gt;
&lt;li&gt;Durability cycles (how many washes it can handle)&lt;/li&gt;
&lt;li&gt;CO₂, water, and energy impact vs virgin materials&lt;/li&gt;
&lt;li&gt;Certifications (GOTS, GRS, OEKO-TEX, etc.)&lt;/li&gt;
&lt;li&gt;Sustainability scoring across multiple dimensions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Forward Cost Curve Forecasting
&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.amazonaws.com%2Fuploads%2Farticles%2Fzxvsw1dcz70qfniri1gx.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%2Fzxvsw1dcz70qfniri1gx.png" alt="Cost Curve Forecasting"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is where the platform really shines. We model material costs 1-10 years into the future, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EU 2027 regulation impact (15% cost increase modelling)&lt;/li&gt;
&lt;li&gt;Supply chain volatility&lt;/li&gt;
&lt;li&gt;Market dynamics and demand fluctuations&lt;/li&gt;
&lt;li&gt;Confidence intervals for risk assessment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The interactive charts, built with Recharts, make complex forecasting data accessible to procurement teams who need to make budget decisions today.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. AI-Powered Specification Matching
&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.amazonaws.com%2Fuploads%2Farticles%2F1emme4f19xziv8ohmjfr.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%2F1emme4f19xziv8ohmjfr.png" alt="AI-Powered Specification Matching"&gt;&lt;/a&gt;&lt;br&gt;
Users can upload their requirements (cost constraints, durability needs, environmental targets) and get ranked recommendations. The AI considers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hard constraints (must-have certifications)&lt;/li&gt;
&lt;li&gt;Soft preferences (cost vs sustainability trade-offs)&lt;/li&gt;
&lt;li&gt;Quantity and timeline requirements&lt;/li&gt;
&lt;li&gt;Supplier reliability and lead times&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The Development Experience with Kiro
&lt;/h2&gt;

&lt;p&gt;Building this platform with Kiro was a transformative experience. Here's what made the difference:&lt;/p&gt;
&lt;h3&gt;
  
  
  Rapid Prototyping to Production
&lt;/h3&gt;

&lt;p&gt;Kiro's ability to understand context and generate production-ready code enabled us to go from concept to working prototype in days, not weeks. When we needed to add the cost forecasting feature, Kiro helped us implement the entire Recharts integration, including proper error handling and responsive design, in a single session.&lt;/p&gt;
&lt;h3&gt;
  
  
  Intelligent Code Suggestions
&lt;/h3&gt;

&lt;p&gt;Rather than just autocompleting syntax, Kiro understood our project's architecture and suggested improvements that aligned with our sustainability focus. When building the material comparison feature, Kiro recommended accessibility improvements and performance optimisations we hadn't considered.&lt;/p&gt;
&lt;h3&gt;
  
  
  Seamless Full-Stack Development
&lt;/h3&gt;

&lt;p&gt;Working across React frontend and Flask backend, Kiro maintained context about our API structure, data models, and component relationships. This resulted in fewer bugs and more consistent patterns throughout the entire application.&lt;/p&gt;
&lt;h2&gt;
  
  
  Real-World Impact: The Numbers That Matter
&lt;/h2&gt;

&lt;p&gt;The platform isn't just technically impressive – it's delivering real sustainability impact:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;60-75% CO₂ reduction&lt;/strong&gt; vs conventional materials&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;15-30% cost premium&lt;/strong&gt; with 3-5 year payback through efficiency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;720-1200 wash cycles&lt;/strong&gt; durability range across material types&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EU 2027 compliance ready&lt;/strong&gt; with built-in regulation modeling&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Deployment: Cloud-Native and Carbon-Neutral
&lt;/h2&gt;

&lt;p&gt;We deployed on Google Cloud Run for automatic scaling and chose carbon-neutral hosting to align with our sustainability mission. The entire platform can be deployed with a single command:&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="c"&gt;# One-command deployment&lt;/span&gt;
./start_demo.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docker containers ensure consistent environments from development to production, and our CI/CD pipeline automatically runs tests and deploys updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next: Scaling Sustainable Impact
&lt;/h2&gt;

&lt;p&gt;The MVP is just the beginning. Our roadmap includes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 2 (Months 2-6):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blockchain traceability for supply chain transparency&lt;/li&gt;
&lt;li&gt;Machine learning models for improved recommendations&lt;/li&gt;
&lt;li&gt;Supplier portal for direct data integration&lt;/li&gt;
&lt;li&gt;Mobile applications for on-the-go access&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Phase 3 (Months 6-12):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enterprise integrations (SAP, Oracle, Microsoft Dynamics)&lt;/li&gt;
&lt;li&gt;Advanced analytics and trend prediction&lt;/li&gt;
&lt;li&gt;International expansion with localised data&lt;/li&gt;
&lt;li&gt;Marketplace features for supplier connections&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Lessons Learned: Building for Impact
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Data Quality Trumps Quantity
&lt;/h3&gt;

&lt;p&gt;Rather than building a massive database of questionable quality, we focused on 10 materials with thoroughly researched, realistic data. Users trust the platform because the numbers are accurate and actionable.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. User Experience Drives Adoption
&lt;/h3&gt;

&lt;p&gt;Sustainability tools often feel like homework. We made ours feel like a premium consumer app. The glass morphism design, smooth animations, and intuitive navigation make complex data approachable.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. AI Should Augment, Not Replace
&lt;/h3&gt;

&lt;p&gt;Our AI doesn't make decisions for users – it provides ranked recommendations with clear reasoning. This fosters trust and enables users to learn about sustainable materials over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Performance Matters for Credibility
&lt;/h3&gt;

&lt;p&gt;Enterprise users expect enterprise performance. Our &amp;lt;200ms API responses and smooth animations signal that this is a professional tool worthy of procurement decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bigger Picture: Technology for Good
&lt;/h2&gt;

&lt;p&gt;This project represents something bigger than just another web application. It's technology being used to accelerate the transition to a circular economy. Every brand that uses our platform to adopt recycled materials is reducing its environmental footprint and supporting sustainable suppliers.&lt;/p&gt;

&lt;p&gt;The fashion industry is responsible for 10% of global carbon emissions. If our platform helps even a small percentage of brands make better material choices, the cumulative impact could be enormous.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;p&gt;The Sustainable Materials Platform is open source and ready to run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/marvinoka4/sustainable-materials-platform
&lt;span class="nb"&gt;cd &lt;/span&gt;sustainable-materials-platform
./start_demo.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In 5 minutes, you'll have a production-ready sustainability platform running locally. The codebase is clean, well-documented, and ready for customisation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: Building the Future We Want
&lt;/h2&gt;

&lt;p&gt;Working on the Sustainable Materials Platform reminded us why we became developers: to build technology that makes the world a better place. With Kiro as our development partner, we were able to focus on solving real problems rather than wrestling with boilerplate code.&lt;/p&gt;

&lt;p&gt;The result is a platform that's not just technically excellent, but genuinely helpful for organisations trying to make more sustainable choices. It's proof that with the right tools and approach, developers can build solutions that matter.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ready to build something that makes a difference? The Sustainable Materials Platform is just the beginning. What will you create next?&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;About the Platform:&lt;/strong&gt;&lt;br&gt;
The Sustainable Materials Platform is a production-ready web application that helps fashion brands discover, compare, and adopt sustainable materials through AI-driven insights, LCA benchmarking, and cost forecasting—built with React, Flask, and deployed on carbon-neutral cloud infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tech Stack:&lt;/strong&gt; React 18, Tailwind CSS, Framer Motion, Flask, Google Cloud Run, Docker&lt;br&gt;
&lt;strong&gt;Impact:&lt;/strong&gt; 60-75% CO₂ reduction potential, EU 2027 compliance ready&lt;br&gt;
&lt;strong&gt;Status:&lt;/strong&gt; Production-ready MVP with comprehensive documentation&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/marvinoka4/sustainable-materials-platform" rel="noopener noreferrer"&gt;View the code on GitHub&lt;/a&gt; | &lt;a href="https://sustainable-materials-frontend-460573069056.us-central1.run.app/" rel="noopener noreferrer"&gt;Try the live demo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>kiro</category>
      <category>sustainability</category>
    </item>
    <item>
      <title>Building Youtangen: An AI-Driven Sustainable Material Platform with Kiro #kiro</title>
      <dc:creator>Marvin Okafor</dc:creator>
      <pubDate>Thu, 04 Sep 2025 23:11:29 +0000</pubDate>
      <link>https://dev.to/marvinoka4/building-youtangen-an-ai-driven-sustainable-material-platform-with-kiro-kiro-5doc</link>
      <guid>https://dev.to/marvinoka4/building-youtangen-an-ai-driven-sustainable-material-platform-with-kiro-kiro-5doc</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;At Youtangen, we’re on a mission to bridge the “valley of death” in sustainable material adoption, empowering mid-tier fashion brands to switch to eco-friendly materials like recycled cotton and polyester without economic or performance risks. For the Code with Kiro Hackathon, we developed a Minimum Viable Product (MVP) that provides AI-driven insights for designers and sourcing VPs, featuring a searchable material database and 1-10 year cost forecasting capabilities. Kiro’s AI-powered IDE transformed our development workflow, slashing prototyping time by 50% and enabling a scalable, carbon-neutral platform hosted on Google Cloud Run. Here’s how we harnessed Kiro to create a game-changer for sustainable fashion.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: Navigating the Sustainable Fashion Maze
&lt;/h2&gt;

&lt;p&gt;The sustainable fashion market is booming (USD 8-12B in 2025, 23.2% CAGR), but brands face significant hurdles: fragmented supply chains, volatile pricing, and scepticism about material performance (e.g., durability, hand feel). Our customer discovery (15+ interviews with industry experts like Anderson and Shetty) revealed that mid-tier brands, such as Veronica Beard or Another Tomorrow, need tools to evaluate sustainable materials quickly and trust their economic viability. Existing platforms, such as Textile Exchange, offer standards, and SwatchOn provides sourcing, but none deliver predictive analytics to overcome adoption barriers. Youtangen fills this gap with AI-driven decision support.&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%2Fpxqjp67ruqhruyrxis10.jpg" 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%2Fpxqjp67ruqhruyrxis10.jpg" alt="Navigating the Maze" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Our Solution: Youtangen’s AI-Powered Platform
&lt;/h2&gt;

&lt;p&gt;Youtangen is a web-based platform designed for mid-tier fashion brands, with two core features:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Material Database with AI Benchmarking&lt;/strong&gt;: A searchable database of 10 materials (recycled cotton, polyester, and virgin baselines) with lifecycle analysis (LCA) comparisons (e.g., CO2, water usage) against user-uploaded specs (cost, durability). For example, it shows that recycled polyester reduces CO2 by 58% compared to virgin polyester, addressing performance scepticism (e.g., Kroner’s concerns about touch/feel).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forward Cost Curve Forecasting&lt;/strong&gt;: An AI tool predicting 1-10 year material costs, factoring in EU 2027 regulations (+15% cost impact) and supply volatility (±5%). This tackles economic barriers (e.g., Shetty’s pricing volatility) and projects 20-30% cost savings for brands.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Hosted on Google Cloud Run with 100% renewable energy, Youtangen aligns with our Carbon13 goal of reducing 10 megatonnes of CO2. The modern UI, styled with Tailwind CSS, offers intuitive search, benchmarking, and interactive cost charts, making it accessible for designers and sourcing VPs.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Kiro Supercharged Our Development
&lt;/h2&gt;

&lt;p&gt;Kiro’s AI-powered IDE was our co-founder in coding, streamlining every phase of development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Inline Coding&lt;/strong&gt;: Kiro generated 70% of our Flask API endpoints (e.g., &lt;code&gt;/api/materials&lt;/code&gt;, &lt;code&gt;/api/benchmark&lt;/code&gt;) and React components (&lt;code&gt;MaterialDatabase.js&lt;/code&gt;, &lt;code&gt;CostForecasting.js&lt;/code&gt;) directly within the IDE. For instance, it suggested optimised MongoDB queries for material searches, reducing coding time from days to hours.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Modal Chat&lt;/strong&gt;: We used Kiro’s chat to brainstorm our database schema (10 materials with LCA data like CO2: 1.5-5.0 kg/kg) and refine our cost forecasting logic (e.g., incorporating EU 2027 impacts). Kiro proposed a &lt;code&gt;numpy&lt;/code&gt;-based forecasting model to sidestep Python 3.13 compatibility issues with &lt;code&gt;statsmodels&lt;/code&gt;, saving us days of debugging.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent Hooks&lt;/strong&gt;: Kiro’s hooks automated critical tasks, such as seeding our MongoDB Atlas database with 10 materials (&lt;code&gt;seed_data.py&lt;/code&gt;) and running API tests. The &lt;code&gt;/.kiro/hooks.py&lt;/code&gt; file logs these automations, cutting 10+ hours of manual work.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spec-Driven Development&lt;/strong&gt;: We defined a &lt;code&gt;/.kiro/spec.yml&lt;/code&gt; to outline our database schema and forecasting algorithm, which Kiro used to generate consistent code structures. This ensured our MVP was scalable and aligned with our vision.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our public GitHub repository ([insert your repo URL here], MIT License) includes the &lt;code&gt;/.kiro&lt;/code&gt; directory, showcasing Kiro’s specs, hooks, and steering logs, which demonstrate its integral role in our workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo: Youtangen in Action
&lt;/h2&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Search and Benchmark&lt;/strong&gt;: Search for “Recycled Cotton Blend” and benchmark against user specs (e.g., cost: $3, durability: 7.8), displaying a 58% CO2 reduction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost Forecasting&lt;/strong&gt;: Generate a 5-year cost curve for recycled polyester, visualising savings with EU 2027 regulation impacts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sustainability Impact&lt;/strong&gt;: Highlight potential for 1M tonnes of CO2 savings through widespread adoption.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Kiro’s inline coding and hooks enabled us to build this polished MVP in weeks, not months. The platform projects 50% user retention, 20% cost savings, and a 70% improvement in trust (as measured by surveys), making it a compelling tool for brands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Details
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tech Stack&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt;: Flask with &lt;code&gt;numpy&lt;/code&gt; for forecasting, &lt;code&gt;sympy&lt;/code&gt; for LCA calculations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;: React with Recharts for interactive charts, styled with Tailwind CSS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database&lt;/strong&gt;: MongoDB Atlas (production) or in-memory for demo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment&lt;/strong&gt;: Google Cloud Run (carbon-neutral hosting).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kiro Features Used&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Inline coding for Flask/React generation.&lt;/li&gt;
&lt;li&gt;Multi-modal chat for schema and algorithm design.&lt;/li&gt;
&lt;li&gt;Agent hooks for database seeding and API testing.&lt;/li&gt;
&lt;li&gt;Spec-driven development via &lt;code&gt;/.kiro/spec.yml&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sustainability&lt;/strong&gt;: Hosted on Google Cloud’s renewable energy, with plans for blockchain-based digital passports for traceability.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;We’re beta testing with 10-20 mid-tier brands (e.g., via Anderson’s intros) to validate our metrics and refine the platform. Future enhancements include integrating real Higg API data, adding blockchain for digital passports, and developing a React Native mobile app. Kiro’s AI made this rapid prototyping possible, and we’re excited to scale Youtangen to transform the sustainable fashion industry.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks to Kiro for empowering us to code smarter and faster. Check out our repo and join the #kiro revolution!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>kiro</category>
      <category>climatetech</category>
      <category>ai</category>
      <category>hackathon</category>
    </item>
    <item>
      <title>The "Ordinariness" of Tech</title>
      <dc:creator>Marvin Okafor</dc:creator>
      <pubDate>Mon, 01 Sep 2025 22:49:13 +0000</pubDate>
      <link>https://dev.to/marvinoka4/the-ordinariness-of-tech-33jp</link>
      <guid>https://dev.to/marvinoka4/the-ordinariness-of-tech-33jp</guid>
      <description>&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%2Fp2r2ut6f2w8cf9nweusq.jpg" 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%2Fp2r2ut6f2w8cf9nweusq.jpg" alt="Image of Tech in relation to Agriculture" width="799" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Technology is undeniably captivating—a dynamic force that connects, streamlines, and enhances human potential. However, its brilliance is a double-edged sword, serving as both a blessing and a curse to itself and to those who wield it. Allow me to explore this duality.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Blessing and a Curse
&lt;/h2&gt;

&lt;p&gt;Technology is a blessing because of its transformative power. It has revolutionised industries, from healthcare to finance, by creating tools that improve efficiency and open new possibilities. However, this same prominence can be a curse. Tech often overestimates its importance, fostering the idea that it is the ultimate solution to all problems. This hubris can cause imbalances, where its role overshadows other vital sectors.&lt;br&gt;
For its practitioners and beneficiaries—myself included—tech is a gateway to opportunity. As a software engineer and data scientist, I have seen firsthand how tech has broadened the scope of industries, creating vibrant spaces for innovation and growth. One of my favourite advantages is the ability to work remotely. Beyond avoiding daily commutes, it has allowed me to collaborate with fascinating businesses across states, countries, and continents. This global connectivity is a remarkable gift.&lt;br&gt;
However, the problem is in external expectations. The hype around technology can create a fragile dependency. During the early “tech boom,” the prevailing sentiment was to “build an app for everything,” and startups thrived from this trend. Now, with the rise of AI, the scene has changed considerably. Non-AI-based tech innovations struggle to stay relevant, suggesting a correction that could have a profound impact on the industry. This does not mean tech is doomed—far from it—but the pendulum of progress sways both ways.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Ordinariness of Tech
&lt;/h2&gt;

&lt;p&gt;When I talk about the “ordinariness” of tech, I’m not downplaying its value. My career, built on designing tech systems, shows its strength. Instead, I’m encouraging a perspective—acknowledging that tech is just one part of a bigger picture. Every sector, from healthcare to agriculture, deals with a fundamental aspect of human life. Tech’s role is distinct in its visibility and flexibility, but it’s not the most important.&lt;br&gt;
Consider healthcare: tech facilitates patient database management, appointment scheduling, and advanced research, making hospitals more efficient. Without these systems, healthcare would struggle to function effectively. But the reverse is equally true—without doctors, nurses, and medical expertise, tech’s tools would be useless. The same logic applies to agriculture. Farmers sustain life itself, and no app can replace their work. Tech is an enabler, not a necessity on par with food, health, or shelter.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Call for Balance
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp0ze3ytjovmswamn7xi6.jpg" 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%2Fp0ze3ytjovmswamn7xi6.jpg" alt="Image denoting Balance" width="799" height="436"&gt;&lt;/a&gt;&lt;br&gt;
My point is straightforward: technology is remarkable in its ability to enhance, but it is commonplace in other industries. It exists to serve, not to dominate. As someone who has prospered during the tech boom, I encourage us to recognise its contributions without exaggerating its importance. By acknowledging technology’s ordinariness, we cultivate a healthier ecosystem where all sectors—healthcare, agriculture, education, and beyond—collaborate harmoniously.&lt;br&gt;
Tech’s brilliance lies in its ability to empower, not to overshadow. Let’s embrace its potential while honouring the equal importance of every field that sustains and enriches human life. In this balance, we envision a future where innovation serves humanity holistically, creating a world that thrives not solely because of technology, but because of the collective strength of all its components.&lt;/p&gt;

</description>
      <category>writing</category>
      <category>webdev</category>
      <category>ai</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
