DEV Community

kingmin8768
kingmin8768

Posted on

Ghost in the Machine: git-spectre โ€” Local AI Digital Sรฉances for Your Haunted Git History

DEV Hacktoberfest Open-Source AI Challenge โ€” Week 4: "Ghost in the Machine" ๐ŸŽƒ๐Ÿ‘ป
A submission for the Overall category and Best Use of Gemma.

Repo: https://github.com/kingmin8768/git-spectre ยท License: MIT ยท Language: Python ยท AI: Google Gemma (open-weight, via Ollama) with a zero-dependency Standalone Haunted Engine fallback


๐Ÿ‘ป The Motivation: Your Commit History Is a Diary. Why Are You Pasting It Into a Chatbot?

Before we get to the ghosts, let's talk about the actual monster under the bed.

Every developer's git history is an intimate document. It contains your real name, your email, the hour you actually go to bed, the functions you were ashamed of, the wip confessions you never cleaned up, and the anatomy of proprietary code your company would rather not see pasted into a hosted LLM's training pipeline "anonymized or otherwise."

And what does the AI-hype era tell us to do with that history? Paste it into a cloud chatbot for "AI-powered commit insights." That's not a feature; that's a data-leak dressed up in a Halloween costume.

git-spectre takes the opposite deal. It summons the ghosts of your repository using a local, open-weight model โ€” Google's Gemma, served on-device through Ollama โ€” and, when no model is installed, a built-in Standalone Haunted Engine that needs nothing but Python. The consequence is the whole point:

  • ๐Ÿ”’ Codebase privacy: commit messages, authors, diffs, and blame never leave the machine. Not once, not anonymized, not "just the metadata."
  • ๐ŸŒ Zero-leakage by architecture: there is no API call to make, no endpoint to misconfigure, no vendor to trust. Privacy here is not a policy โ€” it is physics.
  • โœˆ๏ธ Offline dev: airplane, bunker, cabin in the woods โ€” the sรฉance works anywhere git works.
  • ๐Ÿ’ธ No keys, no costs, no rate limits: no API token in your CI, no meter running on every haunting.

Open-weight models like Gemma are what make this trade possible: you get the ghost, the wit, and the personality โ€” and the blame stays on your disk, where the ghosts belong.

๐Ÿชฆ What I Built

git-spectre โ€” "the haunted git history & digital sรฉance CLI" โ€” treats every repository as what it truly is: a graveyard. Commits are graves, branches are crypts, TODO comments are voices still whispering under the floorboards. Four rites let you interact with the dead:

1. git-spectre haunt โ€” the ghosts review their own code

It reads recent commits (or one you point at), profiles the crime behind each one, and summons the departed developer's spirit to comment on it. Ghost personas are chosen from measurable sins:

Persona Summons when
๐Ÿ•’ The 3 AM Poltergeist commits made between 00:00 and 05:00
๐Ÿ‘น The Colossus a single commit of 500+ changed lines
๐Ÿฉน The Bearer of 'WIP' messages like wip, fix, tmp, asdf
๐Ÿ“… The Weekend Wraith Friday-and-later commits
๐Ÿ‘ป The Forgotten Contributor everything else

Real output from the demo repository:

โ•ญโ”€โ”€โ”€โ”€โ”€ 834f3bf ยท Bob Cursed ยท 31 Oct 2024 03:14 ยท "wip" 1 file(s), +6/-0 โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ The 3 AM Poltergeist ๐Ÿ•’                                                      โ”‚
โ”‚    โœฆ This was written at 03:14 AM-ish. The dead keep those hours. So,        โ”‚
โ”‚ apparently, did Bob Cursed.                                                  โ”‚
โ”‚    โœฆ The commit message reads 'wip'. Archaeologists of the future will weep. โ”‚
โ”‚    โœฆ This grave dates to 31 Oct 2024. Whatever problem it solved, the        โ”‚
โ”‚ problem has since been reborn twice.                                         โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
Enter fullscreen mode Exit fullscreen mode

2. git-spectre seance <file|commit> โ€” the digital sรฉance

Light a candle, close the circle, and interrogate the spirit of whoever wrote a file. On a file, git-spectre runs git blame, identifies the dominant spirit, and puts the questions to them โ€” with the blame summary entered into evidence. This is the feature that hits hardest in code review culture: before you refactor someone's function, hear them explain themselves.

๐Ÿ•ฏ๏ธ Candle lit. Summoning the spirit of Bob Cursedโ€ฆ

โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Sร‰ANCE โ€” Bob Cursed (departed 31 Oct 2024) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ summoned via commit 834f3bf: "wip"                                           โ”‚
โ”‚                                                                              โ”‚
โ”‚   Q: Why did you write this?                                                 โ”‚
โ”‚   A: It was 03:14. I thought I was brilliant. I was merely awake.            โ”‚
โ”‚   Q: What were you thinking at the time?                                     โ”‚
โ”‚   A: The build was broken. The coffee was gone. The code wrote itself and I  โ”‚
โ”‚ signed it.                                                                   โ”‚
โ”‚   Q: Do you repent?                                                          โ”‚
โ”‚   A: I repent of nothing at 03:14. Repentance requires consciousness.        โ”‚
โ”‚   Q: Who else touched what you touched?                                      โ”‚
โ”‚   A: Top spirit: Bob Cursed holds 6 lines of 'cursed.py'. Their fingerprints โ”‚
โ”‚ are everywhere. So are mine.                                                 โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ

The candle is out. The spirit returns to the blame.
Enter fullscreen mode Exit fullscreen mode

3. git-spectre graveyard โ€” Dรญa de los Muertos for your dead code

For the Day of the Dead side of the challenge window, graveyard excavates four kinds of remains โ€” TODO ghosts ๐Ÿ•ฏ๏ธ, commented-out corpses ๐Ÿฅ€, deprecated tombstones ๐Ÿชฆ, and zombie branches ๐ŸงŸ (unmerged, 90+ days cold, found via merge-base --is-ancestor) โ€” and raises an actual ofrenda: a markdown altar, OFRENDA.md, with ASCII tombstones, marigolds, pan de cรณdigo, and Rites of Resurrection that tell you how each kind of dead can either cross over or be laid to rest.

Exhumation complete: 6 soul(s) found in 'demo-spectre'.

โ”ƒ ๐Ÿ•ฏ๏ธ todo           โ”‚ cursed.py:1 โ”‚ # TODO: fix this before the demo
โ”ƒ ๐Ÿฅ€ commented_code โ”‚ cursed.py:2 โ”‚ # def old_summoning():
โ”ƒ ๐Ÿชฆ deprecated     โ”‚ cursed.py:4 โ”‚ @deprecated
โ”ƒ ๐ŸงŸ zombie_branch  โ”‚ doomed      โ”‚ doomed

The altar has been raised: OFRENDA.md
Haunt Index: 34/100 โ€” Actively Haunted ๐Ÿ˜ฑ โ€” cold spots in the blame
Enter fullscreen mode Exit fullscreen mode

And in the generated OFRENDA.md:

        โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
        โ•‘         R. I. P.      โ•‘
        โ•‘                       โ•‘
        โ•‘      TODO: fix th     โ•‘
        โ•‘                       โ•‘
        โ•‘   cursed.py:1         โ•‘
        โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

> *"TODO: fix this before the demo"*
Enter fullscreen mode Exit fullscreen mode

4. git-spectre diagnose โ€” the Haunt Index

One number for how haunted your repository is, from ๐Ÿ•ฏ๏ธ Pristinely Poltergeist-Free to ๐Ÿ’€ Fully Possessed. It weighs witching-hour commits, cursed brief messages, colossal commits, all four kinds of dead code, and sole-author graveyards (a repository haunted by exactly one restless soul is its own kind of sad).

๐Ÿง  Tech Stack & Architecture

Python 3.9+ ยท Typer ยท Rich ยท the git binary ยท Google Gemma (open-weight) via Ollama ยท a hash-seedable Standalone engine ยท pytest

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                      cli.py (typer + rich)                 โ”‚
โ”‚        haunt ยท seance ยท graveyard ยท diagnose ยท epitaph     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                โ”‚                            โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚      git_scanner.py          โ”‚  โ”‚       ghost_engine.py          โ”‚
โ”‚  (read-only exhumation)      โ”‚  โ”‚  dual-mode voices of the dead  โ”‚
โ”‚  ยท commit log + numstat      โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  ยท line-porcelain blame      โ”‚  โ”‚  โ”‚ OllamaGemmaEngine        โ”‚  โ”‚
โ”‚  ยท branch merge-base check   โ”‚  โ”‚  โ”‚  (Gemma via ollama run)  โ”‚  โ”‚
โ”‚  ยท dead-code excavator       โ”‚  โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค  โ”‚
โ”‚    TODO / FIXME / HACK / XXX โ”‚  โ”‚  โ”‚ StandaloneHauntedEngine  โ”‚  โ”‚
โ”‚    commented-out code        โ”‚  โ”‚  โ”‚  (hash-seeded personas,  โ”‚  โ”‚
โ”‚    @deprecated tombstones    โ”‚  โ”‚  โ”‚   zero dependencies)     โ”‚  โ”‚
โ”‚    zombie branches (90d)     โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                โ”‚                            โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                     graveyard.py                           โ”‚
โ”‚   Dรญa de los Muertos renderer โ†’ OFRENDA.md + terminal wake โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
Enter fullscreen mode Exit fullscreen mode

The dual-mode engine is the technical heart. ghost_engine.py exposes one interface with two implementations:

  • OllamaGemmaEngine โ€” detects any pulled Gemma-family model with ollama list (no network), builds a character prompt from commit metadata (author, hour, size, message) and lets Gemma improvise the ghost. When it narrates, the panel is stamped via gemma2:2b so you always know whose voice you're hearing.
  • StandaloneHauntedEngine โ€” a deterministic, hash-seeded template engine. Each persona is selected from measurable properties of the commit (hour band, size band, message laziness, weekday), and the flavor lines are chosen with a RNG seeded by the commit sha โ€” so the same ghost always says the same thing, which makes output reproducible for docs, demos, and CI.

The fallback is seamless and automatic: if Ollama exists but has no Gemma, or fails mid-sรฉance, the standalone engine finishes the haunting and nobody notices the curtain move.

The scanner is strictly read-only. git-spectre never commits, never rewrites history, never touches a ref. The only file it creates is the altar.

Testing: 38 pytest tests build real temporary git repositories โ€” a 3 AM wip commit, a cursed file, a zombie branch abandoned in 2020 โ€” and run every command end-to-end against them, scanner to altar. All 38 pass.

๐ŸŽฌ Demo

pip install git-spectre    # or: pip install . from a clone
ollama pull gemma2:2b      # optional โ€” the standalone engine works without it

cd your-most-haunted-repo

git-spectre haunt          # the dead review their own diffs
git-spectre seance src/    # interrogate the spirit of a file's author
git-spectre graveyard      # raise the OFRENDA.md altar for Dรญa de los Muertos
git-spectre diagnose       # how haunted is this repository, really?
Enter fullscreen mode Exit fullscreen mode

Full captured terminal sessions, including a complete OFRENDA.md altar, are in the repository under demo/. The README carries an extended, copy-pasteable transcript of every rite.

๐ŸŽƒ How It Connects to the Theme

Ghost in the Machine asks what it means for the past to keep living inside our tools. Here's the thing: it already does.

The person who wrote a function at 3 AM in 2021 is still in every line they touched. They answer for it every single time someone runs git blame. Their habits, their shortcuts, their one terrible Friday โ€” all of it persists in the machine, silent, until summoned.

Halloween gives those ghosts a voice: haunt and seance let the departed explain, deflect, and complain about your refactoring plans. Dรญa de los Muertos gives them an altar: graveyard treats dead code not as garbage to delete in shame but as familiares worth honoring before you let them cross over โ€” with marigolds, candles, and rites of resurrection instead of rm -rf.

And the AI twist that makes it all work: the ghost in the machine is running in the machine. A local Gemma model channels your repository's actual dead without a single byte of them leaving the sรฉance room. The ghost was never a metaphor. It was the blame.

๐Ÿ“„ Repository & License


๐Ÿ•ฏ๏ธ Light a candle before you run git blame next time. ๐Ÿ•ฏ๏ธ

Top comments (0)