haunt: the ghost in your git history β€” a local Gemma 2 whisper for your repo's graveyard A developer built haunt, an open-source tool that scores a git repository's files for neglect using only git log metrics β€” dormant, restless, orphaned and debt factors β€” and labels them as orphan spirits, sleepers, poltergeists or revenants. A local Gemma 2 2B model via Ollama narrates the results in a chosen persona, receiving only metrics and commit subjects and never source code, with a deterministic hash-keyed template fallback so the post-commit hook always exits 0. Run against pallets/click, haunt flagged 175 haunted files, including 84 orphan spirits and a top-scoring test file with 13 authors all inactive for 180 days or more. This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine https://dev.to/challenges/hacktoberfest-week4-2026-10-26 . Every repository is quietly becoming a graveyard. Files nobody remembers writing. Tests nobody dares delete. TODOs aging like gravestones. haunt is a ghost for that graveyard β€” and it lives in git, not in a terminal pasted on top. Two small rituals, entirely offline: pip install . then, inside any git repository: haunt install the whisper joins your post-commit hook git commit -m "tomb, again" πŸ•―οΈ Ah, the echoes of lost brilliance in those dusty files, a symphony of potential forever unplayed. The phantom hand of progress reaches out to erase... but will it leave behind anything but shadows? haunt scan which files are the most haunted, and why haunt report --html a narrated HAUNTINGS.md of the worst hauntings haunt persona ancestor swap the voice: victorian, poltergeist, ancestor Three design choices make it a ghost in the machine rather than an AI plugin: git log alone β€” no model, fully explainable: dormant = min age days/365, 1 Γ— min size/500, 1 w 0.35 restless = min churn 90d/20, 1 w 0.25 orphaned = 1 if every author inactive 180d+ w 0.25 debt = min TODO FIXME HACK XXX /10, 1 w 0.15 Scores name their ghosts: πŸ«₯ Orphan spirit all authors gone , πŸ•ΈοΈ Sleeper old, quiet , ⚑ Poltergeist high churn, many hands, no owner , πŸ•―οΈ Revenant dormant for months, then suddenly touched . The model only narrates; it never reads your code. Gemma 2 2B open weights, via Ollama receives metrics and commit subjects β€” never source files send snippets is off by default . A 2B model can't review code, so haunt never asks it to. It asks for what a 2B model is actually good at: voice. The whispers never block a commit. One generate attempt inside a time budget; if the model is cold, busy, or absent, a deterministic template keyed to the commit hash takes over β€” same commit, same line, forever. No retries, no queues. The hook always exits 0. haunt scan on pallets/click https://github.com/pallets/click β€” a 14-year-old, very-much-alive open-source CLI library β€” finds 175 haunted files . The top haunting: score type age churn90 authors debt loc file 0.59 πŸ«₯ Orphan spirit 354d 0 0/13 0 782 tests/test context.py Thirteen authors. All of them inactive. 354 days without a commit. The file has a funeral attended by no one. The full tally: 84 orphan spirits, 81 sleepers, 10 poltergeists β€” a repo at rest that nobody would call haunted until you read the blame. And with the ancestor persona β€” built for DΓ­a de los Muertos, the week's truth that this Halloween stretch is also about honoring the past: πŸͺ” "Their efforts bring warmth and joy to these old halls. May their spirits find solace in the stories shared through this code." The poltergeist handles the noisy places: ⚑ "More flickering, more ghosts. Just don't break a fingernail." Graceful degradation, demonstrated by literally killing Ollama mid-session and committing: πŸ•―οΈ A chill passes through the repository. The commit is buried without ceremony. Same line twice, deterministically keyed to the commit hash β€” and the hook cost the commit nothing. And when the report narrates with Gemma β€” here is haunt's HAUNTINGS.md on that same repo, Victorians mourning real files: age 354d | churn90 0 | authors 0/13 | TODO/FIXME 0 | 782 loc "The pages flutter, whispering tales of what could have been. An echo of promises left unfulfilled, a spectral symphony in the grand ballroom of code. Time slips away like dust, leaving only emptiness where brilliance once resided. Give this ghost a purpose: delete, add a test, document it, or assign an owner to finally give it meaning, however fleeting." The model honestly ends with what the metrics justify β€” every narration closes with a grounded directive, not vibes. On a lonely orphaned doc it got almost tender: "Dust motes dance in the flickering light, each one a memory of a lost chapter, a discarded dream. So many stories whispered between lines of code, now gathering dust like forgotten souls. A quiet voice asks: 'Shall I erase its echo or preserve its fragile remnants?' Name an owner for this forlorn document; at least grant it some solace." Python 3.13, typer , httpx , and raw git subprocesses. No GitPython, no LLM framework. The repo is here https://github.com/Abhinav412/haunt ; MIT licensed; 24 tests pass, including a test that runs a real git commit end-to-end through the installed hook and asserts the whisper appears. git log --format=