<?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: Phúc Phùng</title>
    <description>The latest articles on DEV Community by Phúc Phùng (@phucphungbk).</description>
    <link>https://dev.to/phucphungbk</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%2F4068554%2F3dd22f7a-5bf4-47dd-af97-3c541f2b3171.png</url>
      <title>DEV Community: Phúc Phùng</title>
      <link>https://dev.to/phucphungbk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/phucphungbk"/>
    <language>en</language>
    <item>
      <title>When Your MFC Application Just Disappears: Debugging on a Windows CE 5.0 Device</title>
      <dc:creator>Phúc Phùng</dc:creator>
      <pubDate>Sat, 22 Aug 2026 14:46:18 +0000</pubDate>
      <link>https://dev.to/phucphungbk/when-your-mfc-application-just-disappears-debugging-on-a-windows-ce-50-device-3841</link>
      <guid>https://dev.to/phucphungbk/when-your-mfc-application-just-disappears-debugging-on-a-windows-ce-50-device-3841</guid>
      <description>&lt;p&gt;Back in 2012, I got a rather unusual task.&lt;/p&gt;

&lt;p&gt;I had to build a small application for a specialized fingerprint device from a company I remember as AFIS-Cogent.&lt;/p&gt;

&lt;p&gt;I may be remembering the company or model incorrectly — it has been more than ten years. 😄&lt;/p&gt;

&lt;p&gt;But I still remember the device.&lt;/p&gt;

&lt;p&gt;It was thick.&lt;/p&gt;

&lt;p&gt;It was heavy.&lt;/p&gt;

&lt;p&gt;It had a fingerprint reader, a touchscreen, and a little stylus that you used to poke the screen.&lt;/p&gt;

&lt;p&gt;Yes, poke.&lt;/p&gt;

&lt;p&gt;Not swipe.&lt;/p&gt;

&lt;p&gt;Not pinch-to-zoom.&lt;/p&gt;

&lt;p&gt;Definitely not the smooth touchscreen experience we have today.&lt;/p&gt;

&lt;p&gt;I would guess the device weighed around 1 kg.&lt;/p&gt;

&lt;p&gt;Unfortunately, back then I was still using a feature phone, so I didn't take a photo.&lt;/p&gt;

&lt;p&gt;I've tried searching for the device again recently, but I couldn't find one that looked like the machine I remember.&lt;/p&gt;

&lt;p&gt;Maybe it's just too old now.&lt;/p&gt;

&lt;p&gt;Or maybe my memory has become a little less reliable after ten years. 😄&lt;/p&gt;

&lt;p&gt;The interesting part: it ran Windows CE 5.0&lt;/p&gt;

&lt;p&gt;The device was running Windows CE 5.0.&lt;/p&gt;

&lt;p&gt;If I remember correctly, it had around 128 MB of RAM.&lt;/p&gt;

&lt;p&gt;There was also a cable for transferring data between the device and a computer.&lt;/p&gt;

&lt;p&gt;The device supported C++ and had a graphical interface, so our team decided to use MFC.&lt;/p&gt;

&lt;p&gt;At the time, that seemed like a reasonable choice.&lt;/p&gt;

&lt;p&gt;We weren't trying to build anything fancy.&lt;/p&gt;

&lt;p&gt;The main job of the application was roughly:&lt;/p&gt;

&lt;p&gt;Fingerprint&lt;br&gt;
     ↓&lt;br&gt;
Fingerprint Reader&lt;br&gt;
     ↓&lt;br&gt;
Manufacturer SDK&lt;br&gt;
     ↓&lt;br&gt;
Compare with local fingerprints&lt;br&gt;
     ↓&lt;br&gt;
Result&lt;/p&gt;

&lt;p&gt;The device already had a set of fingerprints loaded locally.&lt;/p&gt;

&lt;p&gt;When someone put their finger on the reader, we used the manufacturer's library to process the fingerprint and perform the matching.&lt;/p&gt;

&lt;p&gt;The manufacturer provided DLLs and documentation describing the functions we needed to call.&lt;/p&gt;

&lt;p&gt;And the documentation was... let's say...&lt;/p&gt;

&lt;p&gt;not short. 😄&lt;/p&gt;

&lt;p&gt;So I spent quite a lot of time reading the documentation to figure out which function did what, what data it expected, and what the result actually meant.&lt;/p&gt;

&lt;p&gt;If the fingerprint couldn't be matched locally, the application would call a server-side service and send the required data to the server for recognition.&lt;/p&gt;

&lt;p&gt;So far, so good.&lt;/p&gt;

&lt;p&gt;Until the application started disappearing.&lt;/p&gt;

&lt;p&gt;Click a button → application gone&lt;/p&gt;

&lt;p&gt;This was the part I remember most clearly.&lt;/p&gt;

&lt;p&gt;Sometimes I clicked a button and...&lt;/p&gt;

&lt;p&gt;the application just disappeared.&lt;/p&gt;

&lt;p&gt;No nice exception message.&lt;/p&gt;

&lt;p&gt;No modern debugger telling me:&lt;/p&gt;

&lt;p&gt;"Hey buddy, this line is probably your problem."&lt;/p&gt;

&lt;p&gt;Nothing.&lt;/p&gt;

&lt;p&gt;It was there.&lt;/p&gt;

&lt;p&gt;I clicked the button.&lt;/p&gt;

&lt;p&gt;And then it wasn't.&lt;/p&gt;

&lt;p&gt;😂&lt;/p&gt;

&lt;p&gt;At first, I had no idea what was happening.&lt;/p&gt;

&lt;p&gt;So I started debugging in the most sophisticated way available to me at the time.&lt;/p&gt;

&lt;p&gt;I wrote messages to a text file.&lt;/p&gt;

&lt;p&gt;Something like:&lt;/p&gt;

&lt;p&gt;step 1&lt;br&gt;
step 2&lt;br&gt;
step 3&lt;br&gt;
step 4&lt;br&gt;
step 5&lt;/p&gt;

&lt;p&gt;Then I ran the application.&lt;/p&gt;

&lt;p&gt;If the file contained:&lt;/p&gt;

&lt;p&gt;step 1&lt;br&gt;
step 2&lt;br&gt;
step 3&lt;/p&gt;

&lt;p&gt;but never reached step 4, I knew the problem was somewhere between those two points.&lt;/p&gt;

&lt;p&gt;Very scientific.&lt;/p&gt;

&lt;p&gt;Very advanced.&lt;/p&gt;

&lt;p&gt;Very 2012. 😄&lt;/p&gt;

&lt;p&gt;But writing to a file for every step was getting annoying.&lt;/p&gt;

&lt;p&gt;So I changed my approach.&lt;/p&gt;

&lt;p&gt;I started using alerts.&lt;/p&gt;

&lt;p&gt;alert("step 1");&lt;br&gt;
alert("step 2");&lt;br&gt;
alert("step 3");&lt;/p&gt;

&lt;p&gt;Run the application.&lt;/p&gt;

&lt;p&gt;Click the button.&lt;/p&gt;

&lt;p&gt;See step 1.&lt;/p&gt;

&lt;p&gt;See step 2.&lt;/p&gt;

&lt;p&gt;See step 3.&lt;/p&gt;

&lt;p&gt;And then...&lt;/p&gt;

&lt;p&gt;Nothing.&lt;/p&gt;

&lt;p&gt;Okay.&lt;/p&gt;

&lt;p&gt;At least now I knew where to start digging.&lt;/p&gt;

&lt;p&gt;Eventually, I found the real problem&lt;/p&gt;

&lt;p&gt;The problem turned out to be related to memory/resource management.&lt;/p&gt;

&lt;p&gt;There were places where I had forgotten to release allocated resources properly.&lt;/p&gt;

&lt;p&gt;On a modern development machine, a small mistake like that might take a while to become visible.&lt;/p&gt;

&lt;p&gt;On a small embedded device with very limited resources, it was a completely different story.&lt;/p&gt;

&lt;p&gt;You didn't have gigabytes of RAM sitting there waiting for you.&lt;/p&gt;

&lt;p&gt;You had a very limited budget.&lt;/p&gt;

&lt;p&gt;And if your application kept holding resources it no longer needed, eventually the system had enough.&lt;/p&gt;

&lt;p&gt;Or rather, it didn't have enough.&lt;/p&gt;

&lt;p&gt;😄&lt;/p&gt;

&lt;p&gt;That experience changed the way I thought about memory.&lt;/p&gt;

&lt;p&gt;Before that, memory was something I knew I had to manage because C++ said so.&lt;/p&gt;

&lt;p&gt;After working on that device, memory became something I could actually feel.&lt;/p&gt;

&lt;p&gt;You made a mistake.&lt;/p&gt;

&lt;p&gt;You ran the application.&lt;/p&gt;

&lt;p&gt;It worked.&lt;/p&gt;

&lt;p&gt;You ran it again.&lt;/p&gt;

&lt;p&gt;Maybe it still worked.&lt;/p&gt;

&lt;p&gt;You did a little more.&lt;/p&gt;

&lt;p&gt;And eventually:&lt;/p&gt;

&lt;p&gt;Bye.&lt;/p&gt;

&lt;p&gt;Your application was gone.&lt;/p&gt;

&lt;p&gt;Debugging without fancy tools&lt;/p&gt;

&lt;p&gt;Looking back, the interesting thing isn't really the bug.&lt;/p&gt;

&lt;p&gt;It's how I had to find it.&lt;/p&gt;

&lt;p&gt;Today, if an application crashes, we have an incredible collection of tools:&lt;/p&gt;

&lt;p&gt;debuggers&lt;br&gt;
stack traces&lt;br&gt;
profilers&lt;br&gt;
memory analyzers&lt;br&gt;
sanitizers&lt;br&gt;
crash reporting&lt;br&gt;
logs&lt;br&gt;
remote debugging&lt;br&gt;
and, of course, AI assistants&lt;/p&gt;

&lt;p&gt;Back then, I didn't have most of those things available in the environment I was working with.&lt;/p&gt;

&lt;p&gt;So I had to reduce the problem manually.&lt;/p&gt;

&lt;p&gt;Does step 1 work?&lt;br&gt;
        ↓&lt;br&gt;
Does step 2 work?&lt;br&gt;
        ↓&lt;br&gt;
Does step 3 work?&lt;br&gt;
        ↓&lt;br&gt;
Where does it stop?&lt;br&gt;
        ↓&lt;br&gt;
What resource is being used there?&lt;br&gt;
        ↓&lt;br&gt;
Who allocated it?&lt;br&gt;
        ↓&lt;br&gt;
Who releases it?&lt;/p&gt;

&lt;p&gt;It was slow.&lt;/p&gt;

&lt;p&gt;But it worked.&lt;/p&gt;

&lt;p&gt;And after doing this several times, something interesting happened.&lt;/p&gt;

&lt;p&gt;I became faster.&lt;/p&gt;

&lt;p&gt;Not because the device became easier.&lt;/p&gt;

&lt;p&gt;I simply started recognizing the patterns.&lt;/p&gt;

&lt;p&gt;The lesson I still remember&lt;/p&gt;

&lt;p&gt;That little Windows CE project wasn't a huge system.&lt;/p&gt;

&lt;p&gt;It wasn't a revolutionary piece of software.&lt;/p&gt;

&lt;p&gt;It was just a small application running on a specialized fingerprint device.&lt;/p&gt;

&lt;p&gt;But it taught me two things that stayed with me.&lt;/p&gt;

&lt;p&gt;The first one is:&lt;/p&gt;

&lt;p&gt;Resources are not infinite.&lt;/p&gt;

&lt;p&gt;Sometimes you work on a machine with 64 GB of RAM and start thinking memory is basically free.&lt;/p&gt;

&lt;p&gt;It isn't.&lt;/p&gt;

&lt;p&gt;It's just somebody else's problem until you move to a device where it isn't. 😄&lt;/p&gt;

&lt;p&gt;The second lesson is more important:&lt;/p&gt;

&lt;p&gt;A difficult problem doesn't necessarily need a complicated solution.&lt;/p&gt;

&lt;p&gt;When I couldn't figure out why the application was disappearing, I didn't have a magical debugging tool.&lt;/p&gt;

&lt;p&gt;So I made one.&lt;/p&gt;

&lt;p&gt;Not a real one.&lt;/p&gt;

&lt;p&gt;Just:&lt;/p&gt;

&lt;p&gt;step 1&lt;br&gt;
step 2&lt;br&gt;
step 3&lt;br&gt;
...&lt;/p&gt;

&lt;p&gt;Then I kept narrowing the problem until I found it.&lt;/p&gt;

&lt;p&gt;After a few rounds, the whole thing became much less scary.&lt;/p&gt;

&lt;p&gt;That's probably one of the most useful things I've learned from working in software.&lt;/p&gt;

&lt;p&gt;You don't always need to know the answer before you start.&lt;/p&gt;

&lt;p&gt;Sometimes you just need to find the next thing you can prove.&lt;/p&gt;

&lt;p&gt;Then another.&lt;/p&gt;

&lt;p&gt;Then another.&lt;/p&gt;

&lt;p&gt;Eventually, the problem gets smaller.&lt;/p&gt;

&lt;p&gt;And when the problem is small enough, you can solve it.&lt;/p&gt;

&lt;p&gt;One more thing&lt;/p&gt;

&lt;p&gt;English isn't my strongest language.&lt;/p&gt;

&lt;p&gt;I've been working in software for many years, and I've probably accumulated quite a few strange production cases like this one.&lt;/p&gt;

&lt;p&gt;But because I'm not very good at English, I haven't shared much of that experience with the wider developer community.&lt;/p&gt;

&lt;p&gt;I'm using my AI assistant to help translate and express what I actually want to say in English.&lt;/p&gt;

&lt;p&gt;The experience, debugging, and technical conclusions are mine.&lt;/p&gt;

&lt;p&gt;AI just helps me communicate them.&lt;/p&gt;

&lt;p&gt;Maybe my English isn't perfect, but I figured it was better to start sharing these stories than to keep them in my head. 🙂&lt;/p&gt;

&lt;p&gt;And if anyone actually remembers those old fingerprint devices running Windows CE...&lt;/p&gt;

&lt;p&gt;I'd love to hear from you.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>cpp</category>
      <category>embedde</category>
      <category>debugging</category>
    </item>
    <item>
      <title>I Built an AI Code Reviewer. Then OWASP Broke It.</title>
      <dc:creator>Phúc Phùng</dc:creator>
      <pubDate>Wed, 19 Aug 2026 22:57:14 +0000</pubDate>
      <link>https://dev.to/phucphungbk/i-built-an-ai-code-reviewer-then-owasp-broke-it-2ika</link>
      <guid>https://dev.to/phucphungbk/i-built-an-ai-code-reviewer-then-owasp-broke-it-2ika</guid>
      <description>&lt;p&gt;Most AI coding tools are very good at helping developers &lt;strong&gt;write code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But I wanted to explore a different question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Can AI help developers find the edge cases and security problems they didn't think about?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question led me to build &lt;strong&gt;EdgeGuard&lt;/strong&gt;, an open-source VS Code extension designed to investigate code from an adversarial perspective.&lt;/p&gt;

&lt;p&gt;The idea is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Try to break the code before production does.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But when I first tested the idea against real security benchmarks, I discovered a problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The AI was too optimistic.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And OWASP exposed it very quickly.&lt;/p&gt;




&lt;h2&gt;
  
  
  The False Negative Trap
&lt;/h2&gt;

&lt;p&gt;I started testing EdgeGuard against the &lt;strong&gt;OWASP Benchmark for Java&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;One of the first things I noticed was surprisingly simple.&lt;/p&gt;

&lt;p&gt;Given code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DatabaseHelper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;doSomething&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"SELECT * FROM USERS WHERE ID='"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"'"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The LLM could see the untrusted HTTP input.&lt;/p&gt;

&lt;p&gt;It could see the SQL construction.&lt;/p&gt;

&lt;p&gt;But it couldn't see what &lt;code&gt;doSomething()&lt;/code&gt; actually did.&lt;/p&gt;

&lt;p&gt;So it made an optimistic assumption:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"This is probably an internal helper that sanitizes the input."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And the result could be:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SAFE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;even though the data was still flowing into a SQL sink.&lt;/p&gt;

&lt;p&gt;This was exactly the kind of false negative I wanted EdgeGuard to find.&lt;/p&gt;

&lt;p&gt;The problem wasn't that the model couldn't understand SQL injection.&lt;/p&gt;

&lt;p&gt;The problem was that &lt;strong&gt;the model was filling in missing information with an optimistic assumption&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Stop Guessing About Unknown Code
&lt;/h2&gt;

&lt;p&gt;I changed the investigation strategy.&lt;/p&gt;

&lt;p&gt;Instead of sending raw code and asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Is this vulnerable?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;EdgeGuard now provides explicit security assumptions and asks the model to preserve taint unless there is evidence that it has been sanitized.&lt;/p&gt;

&lt;p&gt;One important rule became:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;If tainted data enters an unknown function, treat the data as still tainted unless there is evidence that the function sanitizes it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The investigation also became evidence-oriented instead of relying on a simple &lt;code&gt;SAFE&lt;/code&gt; or &lt;code&gt;VULNERABLE&lt;/code&gt; classification.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 1:&lt;/strong&gt; Untrusted input is received from an HTTP request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 2:&lt;/strong&gt; The input enters an unknown helper, so the taint state is preserved.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 3:&lt;/strong&gt; The tainted value is concatenated into a SQL query.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conclusion:&lt;/strong&gt; The data flow represents a potential SQL injection.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That small change made a big difference.&lt;/p&gt;

&lt;p&gt;The AI was no longer being asked to guess what an unknown function &lt;em&gt;probably&lt;/em&gt; did.&lt;/p&gt;

&lt;p&gt;It had to reason from the available evidence and follow explicit security assumptions.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Scale Nightmare
&lt;/h2&gt;

&lt;p&gt;Finding a potential vulnerability in one function is one thing.&lt;/p&gt;

&lt;p&gt;Doing it across thousands of functions is another.&lt;/p&gt;

&lt;p&gt;Large projects contain enormous numbers of methods that simply aren't interesting from a security perspective:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get()
set()
ToString()
Equals()
simple CRUD methods
data mapping
utility functions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sending all of them to an LLM would be wasteful.&lt;/p&gt;

&lt;p&gt;It would also create two immediate problems:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;API rate limits and API cost.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My philosophy has always been:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Start with the simplest solution, and only add complexity when the simple thing breaks.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So I didn't want the LLM to analyze everything.&lt;/p&gt;

&lt;p&gt;I added a local &lt;strong&gt;Static Risk Screening&lt;/strong&gt; stage that runs directly inside VS Code.&lt;/p&gt;

&lt;p&gt;Before making an API call, EdgeGuard parses the code locally and looks for characteristics that make a function worth investigating.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;database sinks&lt;/li&gt;
&lt;li&gt;file-system access&lt;/li&gt;
&lt;li&gt;process execution&lt;/li&gt;
&lt;li&gt;network boundaries&lt;/li&gt;
&lt;li&gt;user-controlled input&lt;/li&gt;
&lt;li&gt;potentially dangerous APIs&lt;/li&gt;
&lt;li&gt;missing validation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The local stage acts as a filter.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;7,000 functions
        ↓
     LLM
        ↓
  $$$$$$$$$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the architecture becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;7,000 functions
        ↓
Local Static Screening
        ↓
High / Medium Risk
        ↓
LLM Investigation
        ↓
Evidence + Verification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes the LLM a &lt;strong&gt;reasoning engine&lt;/strong&gt;, rather than the first line of analysis.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Stress Test: 7,536 Functions
&lt;/h2&gt;

&lt;p&gt;I wanted to know whether this architecture would actually work at project scale.&lt;/p&gt;

&lt;p&gt;So I loaded the entire OWASP Benchmark Java project into VS Code and triggered a workspace scan.&lt;/p&gt;

&lt;p&gt;The scan discovered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;7,536 functions&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2,771 files&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The local screening stage first filtered the code and identified functions that deserved deeper investigation.&lt;/p&gt;

&lt;p&gt;The LLM then focused on the higher-risk candidates instead of blindly processing every function.&lt;/p&gt;

&lt;p&gt;In this test, EdgeGuard reported:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2,145 potential defects&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The findings included security issues such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQL injection&lt;/li&gt;
&lt;li&gt;command injection&lt;/li&gt;
&lt;li&gt;unsafe data flows&lt;/li&gt;
&lt;li&gt;other potentially dangerous input-to-sink paths&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important part for me wasn't simply the number of findings.&lt;/p&gt;

&lt;p&gt;It was that the architecture could move from:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;one function → one LLM request&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;whole workspace → local screening → targeted AI investigation&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;without turning every method into an API call.&lt;/p&gt;




&lt;h2&gt;
  
  
  Testing Three Languages
&lt;/h2&gt;

&lt;p&gt;I also wanted EdgeGuard to work beyond Java.&lt;/p&gt;

&lt;p&gt;So I tested the architecture against projects in three different ecosystems:&lt;/p&gt;

&lt;h3&gt;
  
  
  Java
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;OWASP Benchmark&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  TypeScript
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;OWASP Juice Shop&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  C
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Microsoft eShopOnWeb&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This introduced another problem.&lt;/p&gt;

&lt;p&gt;Java, C#, and TypeScript have very different:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;syntax&lt;/li&gt;
&lt;li&gt;AST structures&lt;/li&gt;
&lt;li&gt;language conventions&lt;/li&gt;
&lt;li&gt;security APIs&lt;/li&gt;
&lt;li&gt;project structures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I didn't want language-specific parsing logic leaking into the investigation engine.&lt;/p&gt;

&lt;p&gt;So I separated the language context layers.&lt;/p&gt;

&lt;p&gt;The architecture became roughly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                EdgeGuard
                    │
          Investigation Engine
                    │
        ┌───────────┼───────────┐
        │           │           │
      Java         C#       TypeScript
     Context      Context      Context
        │           │           │
       AST         AST         AST
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The investigation logic can therefore remain shared while the language-specific context stays isolated.&lt;/p&gt;

&lt;p&gt;This became an important design principle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Share the investigation logic. Isolate the language-specific context.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Evidence Over Assumptions
&lt;/h2&gt;

&lt;p&gt;At this point, I realized that simply generating a vulnerability report wasn't enough.&lt;/p&gt;

&lt;p&gt;An AI can say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"This might be vulnerable."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But what I really want is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Here is how you can reproduce it."&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So EdgeGuard is designed to go beyond detection.&lt;/p&gt;

&lt;p&gt;For potential vulnerabilities, the agent can attempt to construct counterexample inputs and generate runnable verification tests.&lt;/p&gt;

&lt;p&gt;Depending on the language, that can mean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;xUnit&lt;/strong&gt; for C#&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JUnit&lt;/strong&gt; for Java&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mocha&lt;/strong&gt; for TypeScript&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to move from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI says:
"This might be vulnerable."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI hypothesis
      ↓
Counterexample
      ↓
Generated test
      ↓
Execution
      ↓
Evidence
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The principle is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Evidence over assumptions.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




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

&lt;p&gt;Building EdgeGuard changed how I think about AI-assisted code analysis.&lt;/p&gt;

&lt;p&gt;The difficult part isn't simply getting an LLM to understand code.&lt;/p&gt;

&lt;p&gt;The difficult part is controlling what the model is allowed to &lt;strong&gt;assume&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If an unknown helper is assumed safe, a vulnerability can disappear.&lt;/p&gt;

&lt;p&gt;If every function is sent to an LLM, the system becomes expensive and difficult to scale.&lt;/p&gt;

&lt;p&gt;If language-specific context is mixed together, supporting multiple languages becomes increasingly fragile.&lt;/p&gt;

&lt;p&gt;So the architecture ended up combining three different approaches:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Static analysis&lt;/strong&gt; for fast deterministic screening.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LLM investigation&lt;/strong&gt; for reasoning about complex code paths.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verification&lt;/strong&gt; for turning hypotheses into evidence.&lt;/p&gt;

&lt;p&gt;None of these approaches is perfect on its own.&lt;/p&gt;

&lt;p&gt;Together, they are much more interesting.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try to Break Your Own Code
&lt;/h2&gt;

&lt;p&gt;EdgeGuard is an open-source VS Code extension, and it is still evolving.&lt;/p&gt;

&lt;p&gt;The project is available here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/phucphungbk/edgeguard" rel="noopener noreferrer"&gt;https://github.com/phucphungbk/edgeguard&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The idea behind EdgeGuard is deliberately simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't just ask AI to write your code. Ask it how your code could fail.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you work with security-sensitive applications, large codebases, or legacy systems, I'd love to hear how you approach this problem.&lt;/p&gt;

&lt;p&gt;How do you find edge cases?&lt;/p&gt;

&lt;p&gt;How do you deal with false negatives in automated code analysis?&lt;/p&gt;

&lt;p&gt;And most importantly:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do you prove that an AI-generated security finding is actually real?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'm building EdgeGuard to explore those questions.&lt;/p&gt;

&lt;p&gt;Feedback, bug reports, benchmark results, and architectural criticism are all welcome.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>security</category>
      <category>ai</category>
      <category>vscode</category>
    </item>
    <item>
      <title>I don't want to build another AI memory database</title>
      <dc:creator>Phúc Phùng</dc:creator>
      <pubDate>Fri, 14 Aug 2026 15:32:58 +0000</pubDate>
      <link>https://dev.to/phucphungbk/i-dont-want-to-build-another-ai-memory-database-3m0f</link>
      <guid>https://dev.to/phucphungbk/i-dont-want-to-build-another-ai-memory-database-3m0f</guid>
      <description>&lt;p&gt;&lt;strong&gt;What if AI memory was just Markdown, Git, and rules humans can understand?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I have been working with AI more and more recently.&lt;br&gt;
Like many developers, I have tried different AI coding assistants, agents, prompts and workflows.&lt;br&gt;
And after using them for a while, I started noticing a simple problem.&lt;br&gt;
The AI is very good at working with me &lt;strong&gt;today&lt;/strong&gt;.&lt;br&gt;
But tomorrow, I have to explain many things again.&lt;br&gt;
Why did we choose this architecture?&lt;br&gt;
Why did we reject that library?&lt;br&gt;
What have we already tried?&lt;br&gt;
What is still unfinished?&lt;br&gt;
What decisions did we make yesterday?&lt;br&gt;
The longer the project lives, the more painful this becomes.&lt;br&gt;
So I started thinking about AI memory.&lt;br&gt;
I wanted to try something much simpler.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if AI memory was something humans could read?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When people talk about AI memory, there are many technical approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  databases&lt;/li&gt;
&lt;li&gt;  vector databases&lt;/li&gt;
&lt;li&gt;  embeddings&lt;/li&gt;
&lt;li&gt;  RAG&lt;/li&gt;
&lt;li&gt;  semantic search&lt;/li&gt;
&lt;li&gt;  memory services&lt;/li&gt;
&lt;li&gt;  cloud APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These approaches can be very useful.&lt;br&gt;
But I asked myself a different question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Does AI memory have to be complicated if all I want is for an AI agent to remember important project context between sessions?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What if the memory was just a Markdown file?&lt;br&gt;
Something like:&lt;/p&gt;

&lt;p&gt;.ai-memory/ ├── 2026-08-14.md ├── 2026-08-15.md └── 2026-08-16.md&lt;/p&gt;

&lt;p&gt;I can open it.&lt;br&gt;
The AI can read it.&lt;br&gt;
I can edit it.&lt;br&gt;
Git can track it.&lt;br&gt;
I can see exactly what changed.&lt;br&gt;
No special database viewer.&lt;br&gt;
No memory service.&lt;br&gt;
No proprietary format.&lt;br&gt;
Just a file.&lt;br&gt;
And that idea became &lt;strong&gt;Lean AI Memory&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The idea
&lt;/h2&gt;

&lt;p&gt;The core idea is very simple:&lt;/p&gt;

&lt;p&gt;Human  ⇆ Readable Memory  ⇆ AI Agent  ⇆ Git&lt;/p&gt;

&lt;p&gt;The AI and the human share the same project memory.&lt;br&gt;
The memory is stored as Markdown.&lt;br&gt;
Git provides history, diff, branching and collaboration.&lt;br&gt;
The AI can read the memory at the beginning of a session and update it when something important happens.&lt;br&gt;
For example:&lt;/p&gt;

&lt;h1&gt;
  
  
  2026-08-14
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Completed
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Added PDF signature verification. - Added Excel export.
## Decisions&lt;/li&gt;
&lt;li&gt;PDF processing remains local. - SQLite is used for local configuration.
## Problems&lt;/li&gt;
&lt;li&gt;Batch verification is still slow.
## Next&lt;/li&gt;
&lt;li&gt;Investigate batch verification. - Improve error reporting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tomorrow, another AI session can read this.&lt;br&gt;
It does not need me to explain everything from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  But memory is only half of the problem
&lt;/h2&gt;

&lt;p&gt;After thinking about it more, I realized something.&lt;br&gt;
Storing memory is easy.&lt;br&gt;
The harder question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What should the AI remember?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Should it remember every conversation?&lt;br&gt;
Probably not.&lt;br&gt;
Should it save every line of code?&lt;br&gt;
Definitely not.&lt;br&gt;
Should it remember architectural decisions?&lt;br&gt;
Probably.&lt;br&gt;
What about rejected approaches?&lt;br&gt;
Sometimes.&lt;br&gt;
What about unfinished work?&lt;br&gt;
Definitely.&lt;br&gt;
What about project-specific business rules?&lt;br&gt;
That depends on the project.&lt;br&gt;
And this is where I decided not to hard-code the answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rules should be defined by the user
&lt;/h2&gt;

&lt;p&gt;Lean AI Memory uses a simple rules file.&lt;br&gt;
For example:&lt;/p&gt;

&lt;h1&gt;
  
  
  AI Memory Rules
&lt;/h1&gt;

&lt;p&gt;Before starting work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read the latest relevant memory. - Check unfinished work. - Check important architecture decisions.
When making an important decision:&lt;/li&gt;
&lt;li&gt;Record the decision. - Record why it was made. - Record important alternatives that were rejected.
When finishing a work session:&lt;/li&gt;
&lt;li&gt;Record completed work. - Record unresolved problems. - Record what should happen next.
Keep memory concise.
Do not store the entire conversation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important part is:&lt;br&gt;
&lt;strong&gt;These rules are not fixed.&lt;/strong&gt;&lt;br&gt;
You can change them.&lt;br&gt;
A developer may want one type of memory.&lt;br&gt;
A documentation project may need another.&lt;br&gt;
A research project may need something completely different.&lt;br&gt;
A team may have its own conventions.&lt;br&gt;
I don't want Lean AI Memory to pretend that I know what every industry needs.&lt;br&gt;
So I leave the rules open.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The memory format is simple. The rules are yours.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Why Markdown?
&lt;/h2&gt;

&lt;p&gt;Because humans can understand it.&lt;br&gt;
That sounds almost too obvious.&lt;br&gt;
But I think it matters.&lt;br&gt;
Imagine that your AI has remembered an important architectural decision.&lt;br&gt;
Where is it?&lt;br&gt;
Inside a vector database?&lt;br&gt;
Inside embeddings?&lt;br&gt;
Inside some hidden memory service?&lt;br&gt;
Maybe.&lt;br&gt;
But can you open it and understand exactly what the AI remembers?&lt;br&gt;
With Markdown, the answer is simply:&lt;br&gt;
&lt;strong&gt;Yes.&lt;/strong&gt;&lt;br&gt;
You can open the file.&lt;/p&gt;

&lt;p&gt;.ai-memory/2026-08-14.md&lt;/p&gt;

&lt;p&gt;You can read it.&lt;br&gt;
You can edit it.&lt;br&gt;
You can delete something that should not be remembered.&lt;br&gt;
You can commit it.&lt;br&gt;
You can review the diff.&lt;br&gt;
You can even argue with the AI about its own memory. :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Git?
&lt;/h2&gt;

&lt;p&gt;Because software projects already have a memory system.&lt;br&gt;
It's called Git.&lt;br&gt;
Git already gives us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  history&lt;/li&gt;
&lt;li&gt;  diff&lt;/li&gt;
&lt;li&gt;  branches&lt;/li&gt;
&lt;li&gt;  merge&lt;/li&gt;
&lt;li&gt;  rollback&lt;/li&gt;
&lt;li&gt;  collaboration&lt;/li&gt;
&lt;li&gt;  local storage&lt;/li&gt;
&lt;li&gt;  remote backup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I don't see a strong reason to build another complicated history mechanism just for AI memory.&lt;br&gt;
If the AI changes its memory:&lt;/p&gt;

&lt;p&gt;git diff&lt;/p&gt;

&lt;p&gt;can show me what happened.&lt;br&gt;
For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Decision:+ Use PostgreSQL instead of MongoDB. &lt;/li&gt;
&lt;li&gt;Reason:+ Transactional consistency is required.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is a very useful property.&lt;br&gt;
&lt;strong&gt;The AI's memory becomes part of the project's history.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  I intentionally kept the project small
&lt;/h2&gt;

&lt;p&gt;This is probably the part that may look strange if you first see the repository.&lt;br&gt;
Lean AI Memory is tiny.&lt;br&gt;
There is no memory server.&lt;br&gt;
There is no database.&lt;br&gt;
There is no vector search engine.&lt;br&gt;
There is no embedding pipeline.&lt;br&gt;
There is no cloud infrastructure.&lt;br&gt;
The core idea is basically:&lt;/p&gt;

&lt;p&gt;Markdown+Git+Natural-language rules&lt;/p&gt;

&lt;p&gt;That's it.&lt;br&gt;
And this is intentional.&lt;br&gt;
I am not trying to build the most powerful AI memory engine.&lt;br&gt;
I'm trying to answer a smaller question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Can simple, human-readable project memory be useful enough for AI agents?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I don't know the answer yet.&lt;br&gt;
So I built the smallest thing I could.&lt;/p&gt;

&lt;h2&gt;
  
  
  It is not about replacing vector databases
&lt;/h2&gt;

&lt;p&gt;I want to make this clear.&lt;br&gt;
I am not saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Vector databases are bad."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Embeddings are useless."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They solve different problems.&lt;br&gt;
If you have millions of memories and need semantic retrieval, of course you may need more sophisticated technology.&lt;br&gt;
Lean AI Memory is aimed at a different problem.&lt;br&gt;
A project has a relatively small amount of important context:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  decisions&lt;/li&gt;
&lt;li&gt;  conventions&lt;/li&gt;
&lt;li&gt;  unfinished work&lt;/li&gt;
&lt;li&gt;  discoveries&lt;/li&gt;
&lt;li&gt;  assumptions&lt;/li&gt;
&lt;li&gt;  project history&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For that kind of memory, maybe a Markdown file is enough.&lt;br&gt;
Maybe it isn't.&lt;br&gt;
That's exactly what I want people to try.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI memory should not become a black box
&lt;/h2&gt;

&lt;p&gt;One thing I care about is human control.&lt;br&gt;
If an AI remembers something about my project, I should be able to see it.&lt;br&gt;
If it is wrong, I should be able to change it.&lt;br&gt;
If it is no longer relevant, I should be able to remove it.&lt;br&gt;
If I want to know why something is there, Git history should help me understand it.&lt;br&gt;
This gives a very simple relationship:&lt;/p&gt;

&lt;p&gt;AI can write memory  ⇆ Human can inspect memory  ⇆ Human can change memory&lt;/p&gt;

&lt;p&gt;The AI is not the owner of the memory.&lt;br&gt;
&lt;strong&gt;The project is.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  It doesn't have to be only for coding
&lt;/h2&gt;

&lt;p&gt;I initially thought about AI coding agents.&lt;br&gt;
But the more I think about the idea, the less important coding becomes.&lt;br&gt;
The same concept could potentially work for:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documentation&lt;/strong&gt;&lt;br&gt;
Remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  terminology&lt;/li&gt;
&lt;li&gt;  writing conventions&lt;/li&gt;
&lt;li&gt;  decisions&lt;/li&gt;
&lt;li&gt;  unfinished sections&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Research&lt;/strong&gt;&lt;br&gt;
Remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  hypotheses&lt;/li&gt;
&lt;li&gt;  evidence&lt;/li&gt;
&lt;li&gt;  rejected assumptions&lt;/li&gt;
&lt;li&gt;  open questions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Business workflows&lt;/strong&gt;&lt;br&gt;
Remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  process rules&lt;/li&gt;
&lt;li&gt;  decisions&lt;/li&gt;
&lt;li&gt;  exceptions&lt;/li&gt;
&lt;li&gt;  pending work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Team projects&lt;/strong&gt;&lt;br&gt;
Remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  shared decisions&lt;/li&gt;
&lt;li&gt;  conventions&lt;/li&gt;
&lt;li&gt;  responsibilities&lt;/li&gt;
&lt;li&gt;  unresolved issues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Personal AI&lt;/strong&gt;&lt;br&gt;
Remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  preferences&lt;/li&gt;
&lt;li&gt;  ongoing goals&lt;/li&gt;
&lt;li&gt;  important context&lt;/li&gt;
&lt;li&gt;  previous decisions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I don't know what all of these users need.&lt;br&gt;
And I don't want to guess.&lt;br&gt;
That's why the rules are open.&lt;/p&gt;

&lt;h2&gt;
  
  
  The interesting part may actually be the rules
&lt;/h2&gt;

&lt;p&gt;The Markdown format is intentionally boring.&lt;br&gt;
The interesting question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What rules will people create?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example, a software team might define:&lt;/p&gt;

&lt;p&gt;When an architectural decision is made, record the decision, reason and rejected alternatives.&lt;/p&gt;

&lt;p&gt;Another team might say:&lt;/p&gt;

&lt;p&gt;Never store customer data in AI memory.&lt;/p&gt;

&lt;p&gt;A documentation project might say:&lt;/p&gt;

&lt;p&gt;Never change an established business term without recording the reason for the change.&lt;/p&gt;

&lt;p&gt;A research project might say:&lt;/p&gt;

&lt;p&gt;Never treat an assumption as a fact. Record the evidence behind important conclusions.&lt;/p&gt;

&lt;p&gt;These are completely different rules.&lt;br&gt;
And that's okay.&lt;br&gt;
I don't want to build a system that knows all of them.&lt;br&gt;
I want to provide a simple place where people can define them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Lean AI Memory is
&lt;/h2&gt;

&lt;p&gt;In one sentence:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Lean AI Memory is a small, Git-native protocol for persistent AI memory using human-readable Markdown and user-defined natural-language rules.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The design principles are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Human-readable&lt;/li&gt;
&lt;li&gt;  AI-readable&lt;/li&gt;
&lt;li&gt;  Local-first&lt;/li&gt;
&lt;li&gt;  Git-native&lt;/li&gt;
&lt;li&gt;  Rule-driven&lt;/li&gt;
&lt;li&gt;  AI-agnostic&lt;/li&gt;
&lt;li&gt;  Simple&lt;/li&gt;
&lt;li&gt;  Human-controlled&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What it is not
&lt;/h2&gt;

&lt;p&gt;It is not:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  a vector database&lt;/li&gt;
&lt;li&gt;  a semantic search engine&lt;/li&gt;
&lt;li&gt;  a knowledge graph&lt;/li&gt;
&lt;li&gt;  an enterprise memory platform&lt;/li&gt;
&lt;li&gt;  a replacement for every AI memory solution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And I don't want it to become one just because adding features is tempting.&lt;br&gt;
The project should remain understandable.&lt;br&gt;
If someone opens the repository, they should be able to understand the idea without reading a hundred pages of documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why did I open source it?
&lt;/h2&gt;

&lt;p&gt;Because I don't know if I'm right.&lt;br&gt;
That's probably the most honest reason.&lt;br&gt;
I can sit here and explain why Markdown is better.&lt;br&gt;
I can explain why Git is enough.&lt;br&gt;
I can explain why natural-language rules are useful.&lt;br&gt;
But none of that proves the idea.&lt;br&gt;
The only interesting test is:&lt;br&gt;
&lt;strong&gt;Does somebody else find it useful?&lt;/strong&gt;&lt;br&gt;
Maybe someone will use it.&lt;br&gt;
Maybe someone will tell me that the idea is wrong.&lt;br&gt;
Maybe someone will create a rule set I never thought about.&lt;br&gt;
Maybe someone will build an integration.&lt;br&gt;
Maybe nobody will care.&lt;br&gt;
All of those outcomes are useful information.&lt;br&gt;
So I decided to open source it.&lt;br&gt;
You can find the project here:&lt;br&gt;
&lt;a href="https://github.com/phucphungbk/lean-ai-memory" rel="noopener noreferrer"&gt;Lean AI Memory on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A small experiment, not a finished solution
&lt;/h2&gt;

&lt;p&gt;I don't consider Lean AI Memory finished.&lt;br&gt;
Actually, I'm not even sure the underlying idea is correct yet.&lt;br&gt;
That's part of the experiment.&lt;br&gt;
I wanted to build something small enough that people can understand it, modify it and disagree with it.&lt;br&gt;
Maybe AI memory does need databases.&lt;br&gt;
Maybe semantic retrieval will eventually be necessary.&lt;br&gt;
Maybe Markdown will become inconvenient at some scale.&lt;br&gt;
That's fine.&lt;br&gt;
Those are engineering questions.&lt;br&gt;
The first question is simpler:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Can humans and AI share a memory without hiding that memory behind another complicated system?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's what I'm trying to find out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;I've spent a lot of time working on software in different areas.&lt;br&gt;
One thing I have learned is that sometimes the difficult part isn't writing the code.&lt;br&gt;
It is deciding &lt;strong&gt;what should actually be built.&lt;/strong&gt;&lt;br&gt;
With AI, this becomes even more interesting.&lt;br&gt;
AI can generate code extremely quickly.&lt;br&gt;
But it doesn't automatically know what matters to you.&lt;br&gt;
It doesn't automatically know what should be remembered.&lt;br&gt;
It doesn't automatically know which rules your project should follow.&lt;br&gt;
Those things still need to come from somewhere.&lt;br&gt;
So maybe the future of AI memory isn't only about making memory smarter.&lt;br&gt;
Maybe it is also about making memory &lt;strong&gt;understandable&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Maybe AI memory doesn't need to be smarter.&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Maybe it just needs to be understandable.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/phucphungbk/lean-ai-memory" rel="noopener noreferrer"&gt;Lean AI Memory&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;License:&lt;/strong&gt; MIT&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Format:&lt;/strong&gt; Markdown&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;History:&lt;/strong&gt; Git&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Rules:&lt;/strong&gt; Natural language&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you try it, I'd be genuinely interested in seeing what memory rules you come up with.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>llm</category>
      <category>programming</category>
    </item>
    <item>
      <title>I Changed How I Think About AI Memory</title>
      <dc:creator>Phúc Phùng</dc:creator>
      <pubDate>Wed, 12 Aug 2026 16:33:23 +0000</pubDate>
      <link>https://dev.to/phucphungbk/i-changed-how-i-think-about-ai-memory-4mkd</link>
      <guid>https://dev.to/phucphungbk/i-changed-how-i-think-about-ai-memory-4mkd</guid>
      <description>&lt;h1&gt;
  
  
  I Changed How I Think About AI Memory
&lt;/h1&gt;

&lt;p&gt;When I first built &lt;strong&gt;Lean AI Memory&lt;/strong&gt;, I focused too much on the idea.&lt;/p&gt;

&lt;p&gt;AI agents need memory.&lt;/p&gt;

&lt;p&gt;Multi-agent systems can become complicated.&lt;/p&gt;

&lt;p&gt;Maybe we need a simpler approach.&lt;/p&gt;

&lt;p&gt;So I built a small project around that idea.&lt;/p&gt;

&lt;p&gt;But after publishing it, I realized something:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The project was simple. The README wasn't.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It talked too much about what I didn't want to build.&lt;/p&gt;

&lt;p&gt;Multi-agent systems.&lt;/p&gt;

&lt;p&gt;Vector databases.&lt;/p&gt;

&lt;p&gt;Embeddings.&lt;/p&gt;

&lt;p&gt;Cloud services.&lt;/p&gt;

&lt;p&gt;Complex infrastructure.&lt;/p&gt;

&lt;p&gt;But that wasn't really the interesting part.&lt;/p&gt;

&lt;p&gt;The interesting part was much simpler:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Can an AI coding agent remember a project using nothing more than Markdown and Git?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question is what Lean AI Memory is actually about.&lt;/p&gt;

&lt;h2&gt;
  
  
  From "AI Memory System" to "Git-Native Memory"
&lt;/h2&gt;

&lt;p&gt;I changed the positioning of the project to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Git-native memory for AI coding agents.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The idea is intentionally boring:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI Coding Agent
       |
       v
   .ai.rules
       |
       v
  .ai-memory/
       |
       v
      Git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No database.&lt;/p&gt;

&lt;p&gt;No vector database.&lt;/p&gt;

&lt;p&gt;No embeddings.&lt;/p&gt;

&lt;p&gt;No cloud API.&lt;/p&gt;

&lt;p&gt;No additional service.&lt;/p&gt;

&lt;p&gt;Just files inside the project.&lt;/p&gt;

&lt;p&gt;The memory is readable by humans, version-controlled by Git, and can be inspected with the same tools developers already use every day.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git diff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's enough to see what changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Git?
&lt;/h2&gt;

&lt;p&gt;Because software projects already have a memory system.&lt;/p&gt;

&lt;p&gt;It's called Git.&lt;/p&gt;

&lt;p&gt;Git already gives us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;history&lt;/li&gt;
&lt;li&gt;diff&lt;/li&gt;
&lt;li&gt;rollback&lt;/li&gt;
&lt;li&gt;branches&lt;/li&gt;
&lt;li&gt;collaboration&lt;/li&gt;
&lt;li&gt;local storage&lt;/li&gt;
&lt;li&gt;remote backup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So instead of creating another memory infrastructure, I started asking:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if we simply give the AI a small protocol for using the project's existing history?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The AI reads the recent memory before working.&lt;/p&gt;

&lt;p&gt;It works on the project.&lt;/p&gt;

&lt;p&gt;Then it records important decisions, completed work, and unfinished tasks.&lt;/p&gt;

&lt;p&gt;The next session can start from that context.&lt;/p&gt;

&lt;p&gt;That's the whole idea.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep the Memory Small
&lt;/h2&gt;

&lt;p&gt;One thing I learned while building this is that AI memory doesn't need to become a transcript of everything.&lt;/p&gt;

&lt;p&gt;I don't want this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10,000 lines of conversation
       ↓
AI memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I want something closer to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What changed?
Why did we change it?
What did we decide?
What's still unfinished?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# 2026-08-12&lt;/span&gt;

&lt;span class="gu"&gt;## Completed&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Added PDF signature verification.

&lt;span class="gu"&gt;## Decisions&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Keep PDF processing completely local.
&lt;span class="p"&gt;-&lt;/span&gt; Use SQLite for local license storage.

&lt;span class="gu"&gt;## Next&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Add batch verification.
&lt;span class="p"&gt;-&lt;/span&gt; Improve error reporting.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A small amount of useful context may be more valuable than a huge archive of conversations.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Changed in the Repository?
&lt;/h2&gt;

&lt;p&gt;I rewrote the README around this idea.&lt;/p&gt;

&lt;p&gt;The new version focuses on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the actual problem&lt;/li&gt;
&lt;li&gt;the minimal architecture&lt;/li&gt;
&lt;li&gt;how to get started&lt;/li&gt;
&lt;li&gt;personal vs team usage&lt;/li&gt;
&lt;li&gt;why Markdown + Git&lt;/li&gt;
&lt;li&gt;what the project intentionally does NOT try to solve&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also changed the GitHub description to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Git-native memory for AI coding agents. Markdown + Git — no database, embeddings, or cloud API.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The goal is not to claim that this is the best AI memory system.&lt;/p&gt;

&lt;p&gt;It's deliberately the opposite.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I want it to be the smallest useful thing.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Is This Better Than a Real Memory System?
&lt;/h2&gt;

&lt;p&gt;Probably not for every use case.&lt;/p&gt;

&lt;p&gt;If you need semantic search across millions of memories, knowledge graphs, sophisticated retrieval, or enterprise infrastructure, this approach is obviously not enough.&lt;/p&gt;

&lt;p&gt;And that's okay.&lt;/p&gt;

&lt;p&gt;Lean AI Memory is aimed at a different question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What is the minimum infrastructure needed to make an AI coding agent remember a software project?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Maybe the answer is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Markdown + Git.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'm still experimenting with this idea.&lt;/p&gt;

&lt;p&gt;The repository is small, and that's intentional.&lt;/p&gt;

&lt;p&gt;If you're building with AI coding agents, I'd be interested in hearing how you currently handle memory between sessions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you use a memory system, a database, a bunch of Markdown files, or simply start every session from scratch?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/phucphungbk/lean-ai-memory" rel="noopener noreferrer"&gt;https://github.com/phucphungbk/lean-ai-memory&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>aiagents</category>
      <category>opensource</category>
      <category>git</category>
    </item>
    <item>
      <title>1 Year, 5 Tech Stacks, and a 128MB RAM Device: My Rookie Year as a Software Engineer</title>
      <dc:creator>Phúc Phùng</dc:creator>
      <pubDate>Tue, 11 Aug 2026 23:44:01 +0000</pubDate>
      <link>https://dev.to/phucphungbk/1-year-5-tech-stacks-and-a-128mb-ram-device-my-rookie-year-as-a-software-engineer-5g4g</link>
      <guid>https://dev.to/phucphungbk/1-year-5-tech-stacks-and-a-128mb-ram-device-my-rookie-year-as-a-software-engineer-5g4g</guid>
      <description>&lt;p&gt;Intro: The Transition of a Computer Engineering Student&lt;br&gt;
My starting point upon graduation wasn't strictly in software engineering; I actually majored in Computer Engineering. However, as fate would have it, the day I stepped out into the real world with my degree, I took a sharp turn to become a Software Developer.&lt;br&gt;
At that time, my baggage contained nothing but some foundational knowledge and a strict mindset: If I'm working, I can no longer be lazy. If I don't do my job, absolutely no one will do it for me. That pressure of responsibility forced me to grow up, think independently, and learn to swim in the whirlpool of technology.&lt;/p&gt;

&lt;p&gt;Episode 1: The "Welcome Gift" Named Oracle Database&lt;br&gt;
During my first days on the job in 2011, I received a memorable challenge: a thick stack of documentation on how to install Oracle Database on my assigned desktop. For a rookie, Oracle was famously known as a complex and "heavyweight" relational database. Configuring environment variables, listeners, or tnsnames.ora felt like reading encrypted code at the time.&lt;br&gt;
After days of struggling, blindly reinstalling it over and over, the local screen finally showed a successful connection via PL/SQL Developer. The "exhausting" experience of those early days laid the foundation for me to battle with Oracle Forms &amp;amp; Reports — an incredibly popular technology in large enterprise systems back then. It taught me my very first lesson: Don't fear new technology; just get your hands dirty. Reinstall it a dozen times, and you'll naturally understand its core.&lt;/p&gt;

&lt;p&gt;Episode 2: Java, Play Framework, and the "Don't Hide Your Ignorance" Mindset&lt;br&gt;
Not long after warming up my seat in the Oracle team, I was moved to the Java team to code Desktop applications using Java JWT/Swing. But before I could even settle in, the Department Head decided to pivot the entire team to a very new technology at the time: Play Framework.&lt;br&gt;
Today, this name might have faded into the past with few remembering it, but back then, it was a whole new world. I survived this period of constant shifting thanks to a core philosophy: Don't be afraid of people judging you as incompetent, be willing to learn, and absolutely do not hide your ignorance. If you don't know, ask; if you don't understand, dig deeper. That "shameless" attitude unlocked my ability to proactively learn any system.&lt;/p&gt;

&lt;p&gt;Episode 3: Epiphany on the Core of PHP, MySQL, and Legacy ASP.NET Web Forms&lt;br&gt;
The technology merry-go-round showed no signs of stopping. Right after Java, I was pushed straight into an old project running on PHP and MySQL. Then came SharePoint, bringing the opportunity to get familiar with the Microsoft ecosystem including C# and SQL Server, and even some legacy ASP.NET Web Forms projects with their convoluted Page Lifecycles and ViewStates.&lt;br&gt;
Facing a basket of constantly changing technologies within just a year, my mind suddenly cleared, and I experienced a massive leap in my thinking: A new language? So what? A new DB? Nothing to fear. There must be core commonalities between them! Instead of rote-learning every line of syntax, I chose a top-down approach:&lt;/p&gt;

&lt;p&gt;Focus on the Business Logic: Any technology must serve a business problem.&lt;/p&gt;

&lt;p&gt;Debug when wrong: No more guessing games. Just set breakpoints to watch the data flow and logically deduce why the system behaves the way it does.&lt;/p&gt;

&lt;p&gt;After those projects, I realized that SQL fundamentally shares a common standard (ANSI SQL), only differing in a few specialized functions per DB type. From that moment on, I didn't have to waste too much time "relearning" from scratch every time I switched databases or languages.&lt;/p&gt;

&lt;p&gt;Episode 4: The Optimization Battle and the "Cherish Every Byte" Lesson&lt;br&gt;
The peak of my first-year challenges was writing fingerprint recognition software for an AFIS handheld device. It was a hardware "monster" weighing nearly 1kg, running Windows CE 5.0, with a meager RAM of exactly... 128MB, written in MFC (C++).&lt;br&gt;
The mission was to capture fingerprints and match them locally; if it failed, call an API to push the data to the Server. With a tiny 128MB of RAM, continuous image data processing turned the memory into a sensitive battlefield. Just one "forgotten" pointer deallocation (Memory Leak), and the Windows CE OS would mercilessly "kill" the app.&lt;br&gt;
Back then, we didn't have fancy Profiler tools, and phones were still "dumb bricks," so there were no smartphones to take pictures for documentation. Finding a memory leak relied entirely on step-by-step debugging, observation, and intuition. Through hundreds of crashes, errors naturally turned into experience and reflexes. From that grueling battle, I forged a professional standard that has stayed with me ever since: When resources are limited, you must pay attention to every memory block to avoid leaks. You must write clean code and be responsible for every byte of data, no matter how powerful modern machines are.&lt;/p&gt;

&lt;p&gt;Conclusion: The Master Key of a Software Engineer&lt;br&gt;
Looking back at my "stormy" first year of working, I silently appreciate the immense pressure and constant changes of those days. Ultimately, technologies, languages, or frameworks are merely vehicles; they are just the branches. The roots that help a developer go far and never fear obsolescence are: A business logic mindset, logical debugging skills, and an attitude of not hiding your ignorance.&lt;br&gt;
Don't turn yourself into a code monkey boxed within a specific language. Be an engineer who solves problems with an adaptable mindset, because technologies may rise and fall, but the ability to adapt to the market lasts forever.&lt;/p&gt;

</description>
      <category>career</category>
      <category>beginners</category>
      <category>softwareengineering</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Why I stopped using Vector DBs for AI Memory (and used Git + Markdown instead)</title>
      <dc:creator>Phúc Phùng</dc:creator>
      <pubDate>Sun, 09 Aug 2026 23:42:52 +0000</pubDate>
      <link>https://dev.to/phucphungbk/why-i-stopped-using-vector-dbs-for-ai-memory-and-used-git-markdown-instead-3k86</link>
      <guid>https://dev.to/phucphungbk/why-i-stopped-using-vector-dbs-for-ai-memory-and-used-git-markdown-instead-3k86</guid>
      <description>&lt;p&gt;Hey DEV community! 👋&lt;/p&gt;

&lt;p&gt;Like many of you, I've been heavily experimenting with AI Agents recently. But as a software architect who hates unnecessary overhead, watching the community default to spinning up heavy Vector DBs and complex graph frameworks &lt;em&gt;just&lt;/em&gt; to store conversation context felt like massive over-engineering.&lt;/p&gt;

&lt;p&gt;We often use massive systems to solve small problems. I wanted an AI memory system that is zero-cost, serverless, and completely transparent. So, I built a lean alternative.&lt;/p&gt;

&lt;p&gt;🔥 &lt;strong&gt;Talk is cheap, here is the repo:&lt;/strong&gt; &lt;a href="https://github.com/phucphungbk/lean-ai-memory" rel="noopener noreferrer"&gt;https://github.com/phucphungbk/lean-ai-memory&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Lean Approach: Back to Basics
&lt;/h3&gt;

&lt;p&gt;Instead of adding new layers of infrastructure, I looked at what we already have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Git as the Core Engine:&lt;/strong&gt; We already use Git for version control. It turns out it's absolutely perfect for managing conversation history. You can easily track, diff, and rollback an AI's "thought process" just like reverting a bad commit.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Markdown as the Storage Format:&lt;/strong&gt; It’s lightweight, humans can read and debug it instantly, and LLMs parse it perfectly without needing complex embedding pipelines.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Zero-cost &amp;amp; Portable:&lt;/strong&gt; It can be packaged as an independent module and integrated directly into internal automation tools without incurring any DB maintenance costs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why I open-sourced this
&lt;/h3&gt;

&lt;p&gt;I’m sharing this with a completely open mindset. Instead of optimizing it in a silo, I want to see how this framework holds up in the wild. I'm highly anticipating the community bringing their own battle-tested custom rules into the system to push its boundaries.&lt;/p&gt;

&lt;p&gt;I’d love for you guys to clone it, tear the architecture apart, run some tests, and drop your feedback or PRs. &lt;/p&gt;

&lt;p&gt;Let me know what you think in the comments! Happy coding! 🚀&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>ai</category>
      <category>opensource</category>
      <category>git</category>
    </item>
  </channel>
</rss>
