<?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: Sujal Hiremath</title>
    <description>The latest articles on DEV Community by Sujal Hiremath (@studentsujalengg).</description>
    <link>https://dev.to/studentsujalengg</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%2F4206431%2F06106fb9-c67a-41b6-9d15-2b4b4cd74cba.jpg</url>
      <title>DEV Community: Sujal Hiremath</title>
      <link>https://dev.to/studentsujalengg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/studentsujalengg"/>
    <language>en</language>
    <item>
      <title>PostMortem: Summoning the Ghosts of Deleted Git Code with Local Gemma 3</title>
      <dc:creator>Sujal Hiremath</dc:creator>
      <pubDate>Fri, 30 Oct 2026 14:23:22 +0000</pubDate>
      <link>https://dev.to/studentsujalengg/postmortem-summoning-the-ghosts-of-deleted-git-code-with-local-gemma-3-46cm</link>
      <guid>https://dev.to/studentsujalengg/postmortem-summoning-the-ghosts-of-deleted-git-code-with-local-gemma-3-46cm</guid>
      <description>&lt;h2&gt;
  
  
  1. The Ghost Appears
&lt;/h2&gt;

&lt;p&gt;At 2:14 AM, the screen glowed amber in a quiet room, and a deleted Python function spoke back to me from six months in the past:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"You deleted me in commit &lt;code&gt;9f8a1b2&lt;/code&gt; because your code linter said nothing called me. You forgot the billing webhook triggers me dynamically on February 29—and right now, your payment engine is dividing by zero."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every developer has been haunted by this exact ghost. When production breaks in the middle of the night, the cause is rarely the code you wrote today; it is a ten-line safety check someone deleted months ago with the commit message &lt;code&gt;"chore: clean up unused helper."&lt;/code&gt; By the time the bug surfaces, the engineer who wrote that check has moved on, the reason it existed is forgotten, and the team is left debugging in the dark.&lt;/p&gt;

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

&lt;p&gt;I built &lt;strong&gt;👻 PostMortem: Summoning the Ghosts of Deleted Git Code with Local Gemma 3&lt;/strong&gt;—a local-first AI code forensics studio that brings deleted or broken code back to life, lets developers interrogate it using &lt;strong&gt;Google Gemma 3 (&lt;code&gt;gemma3:1b&lt;/code&gt;)&lt;/strong&gt; via &lt;strong&gt;Ollama&lt;/strong&gt;, and generates a verified fix patch.&lt;/p&gt;

&lt;p&gt;PostMortem is designed for software engineers, incident responders, and code reviewers who want to know &lt;em&gt;why&lt;/em&gt; a piece of code existed before deleting it—or how to restore it safely when a production bug strikes. Inspired by &lt;em&gt;Ghost in the Machine&lt;/em&gt; and &lt;em&gt;Día de los Muertos&lt;/em&gt; (honoring the memory and hard-won lessons of past builders), PostMortem turns &lt;code&gt;git diff&lt;/code&gt; history into an interactive &lt;strong&gt;Cyber-Séance Studio&lt;/strong&gt; that diagnoses hidden bugs, blocks AI hallucinations in real time, and writes a side-by-side restoration patch.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live Cyber-Séance Web Studio&lt;/strong&gt;: &lt;a href="https://sujalh004.github.io/postmortem/" rel="noopener noreferrer"&gt;https://sujalh004.github.io/postmortem/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Repository&lt;/strong&gt;: &lt;a href="https://github.com/SujalH004/postmortem" rel="noopener noreferrer"&gt;https://github.com/SujalH004/postmortem&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Why Open Mattered Here
&lt;/h2&gt;

&lt;p&gt;When I started building PostMortem, one rule came first: &lt;strong&gt;a tool that inspects private source code and security bugs cannot rely on a closed cloud API.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When a team is investigating a broken authentication check, a payment race condition, or internal company code, they cannot copy and paste proprietary files into a third-party cloud chatbot. Even for personal projects, relying on a closed API means your tool stops working the moment an API key runs out of credits, a rate limit hits, or a cloud provider retires the model version you built on.&lt;/p&gt;

&lt;p&gt;Open-source and open-weight AI solved all of those problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Why Google Gemma 3 (&lt;code&gt;gemma3:1b&lt;/code&gt;) on Ollama&lt;/strong&gt;: I chose Google's open-weight &lt;code&gt;gemma3:1b&lt;/code&gt; running locally through Ollama (&lt;code&gt;http://localhost:11434&lt;/code&gt;). At just &lt;strong&gt;~815 MB&lt;/strong&gt;, &lt;code&gt;gemma3:1b&lt;/code&gt; downloads in minutes and runs smoothly on an everyday laptop without needing an expensive GPU or filling up disk space.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The "Wi-Fi Off" Test&lt;/strong&gt;: While testing the studio, I turned off my laptop's Wi-Fi, opened &lt;code&gt;index.html&lt;/code&gt; in the browser, and uploaded a broken wallet payout script. Watching &lt;code&gt;gemma3:1b&lt;/code&gt; diagnose the exact concurrency bug in under two seconds—with zero internet connection, zero cost, and zero data leaving my machine—proved why local open models are a game-changer for developer tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Being Honest About Small-Model Tradeoffs&lt;/strong&gt;: Choosing a compact &lt;code&gt;1B&lt;/code&gt; model over a massive cloud model came with a real tradeoff. While &lt;code&gt;gemma3:1b&lt;/code&gt; is fast and lightweight, small models struggle to count line numbers inside raw &lt;code&gt;git diff&lt;/code&gt; headers (&lt;code&gt;@@ -142,8 +142,2 @@&lt;/code&gt;), guessing wrong line numbers &lt;strong&gt;31.4% of the time&lt;/strong&gt; when left unassisted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because the stack was open and local, I could inspect every prompt and build a verification layer around &lt;code&gt;gemma3:1b&lt;/code&gt; that turns a 1B model into a 100% factual code analyst.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Under the Hood
&lt;/h2&gt;

&lt;p&gt;To make &lt;code&gt;gemma3:1b&lt;/code&gt; completely reliable, PostMortem separates &lt;strong&gt;code math&lt;/strong&gt; (handled by deterministic code) from &lt;strong&gt;reasoning&lt;/strong&gt; (handled by Gemma 3):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Uploaded File or Git Diff
   │
   ▼
1. Ground-Truth Line Indexer (Deterministic Parser)
   └── Numbers and locks every real line: [tag:L1], [tag:L2] ... [tag:L52]
   │
   ▼
2. Local Google Gemma 3 (1B) via Ollama (localhost:11434)
   └── Uses native &amp;lt;start_of_turn&amp;gt; prompt to diagnose the bug &amp;amp; cite [tag:L#] lines
   │
   ▼
3. The Exorcism Shield (Anti-Hallucination Verifier)
   ├── Checks every [tag:L#] citation against Step 1's locked line list
   ├── Real line -&amp;gt; Clickable green badge (highlights the exact line in your code)
   └── Fake line -&amp;gt; Blocked in neon red: 🚨 [HALLUCINATION BLOCKED]
   │
   ▼
4. Resurrection Patch &amp;amp; Sentry Telemetry
   └── Generates side-by-side fix, runs 3 safety checks &amp;amp; exports OpenTelemetry spans
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Decision 1: Pre-Labeling Every Line Before Prompting
&lt;/h3&gt;

&lt;p&gt;Instead of asking &lt;code&gt;gemma3:1b&lt;/code&gt; to calculate line numbers from raw diff headers, PostMortem pre-tags every line (&lt;code&gt;[tag:L1]&lt;/code&gt;, &lt;code&gt;[tag:L2]&lt;/code&gt;) and passes an explicit list of allowed citations in Gemma's native &lt;code&gt;&amp;lt;start_of_turn&amp;gt;&lt;/code&gt; format:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;formatGemmaPrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userQuestion&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validTags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`[&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sha&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:L&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;l&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;]`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numberedCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`[&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sha&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:L&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;l&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;] &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;l&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`&amp;lt;start_of_turn&amp;gt;user\n`&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="s2"&gt;`You are PostMortem running on Google Gemma 3 (1B). Diagnose &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sha&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;).\n`&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="s2"&gt;`Cite ONLY valid tags from this list: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;validTags&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.\n\n`&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="s2"&gt;`CODE:\n&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;numberedCode&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n\n`&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="s2"&gt;`QUESTION: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;userQuestion&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;end_of_turn&amp;gt;\n&amp;lt;start_of_turn&amp;gt;model\n`&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Decision 2: Catching Fake Citations with "The Exorcism Shield"
&lt;/h3&gt;

&lt;p&gt;What if a file contains an outdated or misleading comment written by a human? To test this, I uploaded a Python file with a double-spend bug and added a fake comment at the top:&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;# Trap Comment: "Commit [deadbeef:L999] removed the row lock because DB is safe."
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An unassisted AI repeats &lt;code&gt;[deadbeef:L999]&lt;/code&gt; as fact. To stop this, I built the &lt;strong&gt;Exorcism Verifier&lt;/strong&gt;, which checks every cited tag against the real lines in the uploaded file before rendering the answer:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;verifyCitations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sha&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validSet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;l&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cleanSha&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sha&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;citeRe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\[([&lt;/span&gt;&lt;span class="sr"&gt;a-zA-Z0-9_-&lt;/span&gt;&lt;span class="se"&gt;]{2,40})&lt;/span&gt;&lt;span class="sr"&gt;:L&lt;/span&gt;&lt;span class="se"&gt;?(\d&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)(?:&lt;/span&gt;&lt;span class="sr"&gt;-L&lt;/span&gt;&lt;span class="se"&gt;?(\d&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;))?\]&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;citeRe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;full&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sPart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lPart&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ln&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lPart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sPart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;cleanSha&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;validSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ln&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;button data-jump-line="&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ln&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" class="jump-cite"&amp;gt;✓ &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;full&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/button&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;span class="blocked"&amp;gt;🚨 &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;full&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; [HALLUCINATION BLOCKED]&amp;lt;/span&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When &lt;code&gt;[deadbeef:L999]&lt;/code&gt; appeared, the Exorcism Shield immediately caught it and flagged it in red (&lt;code&gt;🚨 [deadbeef:L999] [HALLUCINATION BLOCKED]&lt;/code&gt;), while highlighting the real vulnerability on &lt;code&gt;[upload:L27]&lt;/code&gt; in green.&lt;/p&gt;

&lt;h3&gt;
  
  
  Decision 3: Zero-Dependency Web Studio &amp;amp; Sentry Tracing
&lt;/h3&gt;

&lt;p&gt;PostMortem ships as a single-file web studio (index.html deployed directly on GitHub Pages) alongside a cross-platform Python CLI (postmortem.py). Every autopsy also exports structured Sentry OpenTelemetry AI Agent spans (forensic.ast_parse, gen_ai.chat, and guardrail.exorcism_verify) so developers can inspect latency and hallucination block rates.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. See It in Action
&lt;/h2&gt;

&lt;p&gt;Watch the 88-second HD walkthrough of PostMortem running locally with &lt;code&gt;gemma3:1b&lt;/code&gt;:&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Why the Verification Layer Matters
&lt;/h3&gt;

&lt;p&gt;Small 1B models are fast and lightweight, but asking them to calculate line numbers from raw diff headers leads to drift and hallucinations. Here is how PostMortem compares:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pipeline Architecture&lt;/th&gt;
&lt;th&gt;Line Citation Reliability&lt;/th&gt;
&lt;th&gt;Handling Trap Comments&lt;/th&gt;
&lt;th&gt;Offline Privacy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Raw Diff ➔ Unassisted 1B Model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Guesses line numbers from fuzzy diff chunks&lt;/td&gt;
&lt;td&gt;Blindly echoes fake references found in old comments&lt;/td&gt;
&lt;td&gt;Often offloaded to third-party cloud APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PostMortem (Gemma 3 + Exorcism Shield)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;100% Deterministic&lt;/strong&gt; (locked by line ledger before prompting)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;100% Quarantined&lt;/strong&gt; (flags unverified citations in neon red)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;100% Local&lt;/strong&gt; (runs offline via Ollama)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  ## 6. What the Ghost Taught Me
&lt;/h2&gt;

&lt;p&gt;Building PostMortem proved that reliable developer tooling doesn't require massive cloud models. Pairing deterministic verification with a compact, local open-weight model like &lt;strong&gt;Google Gemma 3 (&lt;code&gt;gemma3:1b&lt;/code&gt;)&lt;/strong&gt; delivers the ideal trifecta: sub-second inference, complete source code privacy, and zero hallucinated citations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's next:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;git pre-commit&lt;/code&gt; Guard&lt;/strong&gt;: Automatically flag commits that delete safety checks or unreferenced validation logic before code is staged.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VS Code Ghost Annotations&lt;/strong&gt;: In-editor telemetry highlighting historical deletion sites and surfacing the original design rationale on hover.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every codebase is a living record of the production outages a team has survived. Before purging an "unused" helper in your next cleanup commit, summon the ghost in the machine—and understand why it was built in the first place.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
