This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine
Every function you've ever deleted is still haunting your repo. It's in .git, every version of it, on every branch. You just can't reach it, because the only way in is by name (git log -S imageFilesFromClipboard), and the whole reason you're looking is that you don't remember the name.
I remember what it did. "The thing that pulled pasted images out of the clipboard. I deleted it in July, I think."
So for Halloween week I built a séance for git.
What I Built
Git Séance finds every function that ever lived in your repos and has since died, and lets you call one back by describing it:
$ seance summon "paste images from the clipboard" -k 2
17 0.82 imageFilesFromClipboard arivu-agent/desktop/renderer/src/App.tsx
born 2026-06-21, died 2026-07-03 in f2e18500 "Add drag-and-drop image attachments"
15 0.69 pullRequestCheckLogCommand arivu-agent/src/agent/taskWorktree.ts
born 2026-07-04, died 2026-07-05 in 39d376bc "Broaden PR check evidence capture"
$ seance raise 17
// imageFilesFromClipboard from desktop/renderer/src/App.tsx, last seen in f2e18500^
function imageFilesFromClipboard(clipboard: DataTransfer) {
const files = Array.from(clipboard.files).filter((file) => SUPPORTED_IMAGE_TYPES.has(file.type));
...
It tells you when each ghost was born, when it died, and the commit that killed it (it arrived with the project's first commit on June 21 and died on July 3 in "Add drag-and-drop image attachments", replaced by a better design). raise brings back its last living version.
Everything runs locally with EmbeddingGemma 2, an open-weight model. Your history, including the parts you deleted on purpose, never leaves your laptop.
Demo
Two of my public repos, my coding agent Arivu and Bharat Choropleth, a map library:
$ seance index ~/Documents/arivu-agent ~/Documents/"Bharath Choropleth"
arivu-agent: 26 ghosts (3 s)
Bharath Choropleth: 7 ghosts (1 s)
embedding 33 unique ghosts…
$ seance summon "warn me before running dangerous shell commands" -k 1
19 0.81 detectCommandWarnings arivu-agent/desktop/renderer/src/App.tsx
born 2026-06-21, died 2026-07-03 in 528eea09 "Implement Arivu harness app features"
$ seance summon "fetch live temperatures for each region" -k 2
27 0.86 start Bharath Choropleth/examples/observatory/live/app.js
born 2026-09-06, died 2026-09-06 in 15edc63c "feat(examples): live temperature as the first indicator in a"
31 0.83 temperaturesFor Bharath Choropleth/examples/observatory/live/app.js
born 2026-09-06, died 2026-09-06 in 15edc63c "feat(examples): live temperature as the first indicator in a"
The code never says "dangerous": detectCommandWarnings just looks for things like rm -rf and sudo. Meaning, not keywords.
Code
shashankbudem
/
git-seance
Summon deleted functions back from your git history by describing them. Local, on EmbeddingGemma 2.
Git Séance
Every function you ever deleted is still in your git history. Git Séance lets you call it back by describing it.
You remember that you wrote it: "the thing that pulled pasted images out of the clipboard", deleted sometime in July
You don't remember its name, so git log -S can't help you. Git Séance walks every version of every file on every
branch, finds the functions that no longer exist at HEAD, and lets you search them by meaning with
EmbeddingGemma 2, an open-weight model running on your laptop.
$ seance summon "paste images from the clipboard" -k 2
17 0.82 imageFilesFromClipboard arivu-agent/desktop/renderer/src/App.tsx
born 2026-06-21, died 2026-07-03 in f2e18500 "Add drag-and-drop image attachments"
15 0.69 pullRequestCheckLogCommand arivu-agent/src/agent/taskWorktree.ts
born 2026-07-04, died 2026-07-05 in 39d376bc "Broaden PR check evidence capture"
$ seance raise 17
// imageFilesFromClipboard from desktop/renderer/src/App.tsx, last seen in f2e18500^ (git -C ~/Documents/arivu-agent show f2e18500^:desktop/renderer/src/App.tsx)…About 220 lines of Python, plus a smoke test and the evaluation script.
How I Built It
I built this with Claude Code as my pair programmer: I picked the idea and made the calls, and the agent did most of the typing and the evaluation runs.
1. Read the whole graveyard in one pass. git log --all --raw lists every version (blob) of every source file on every branch, with the commit that created it and the commit that replaced it. One git cat-file --batch stream reads them all. My 89-commit agent repo takes 3 seconds.
2. Find the functions. tree-sitter pulls every function of five or more lines out of TypeScript, JavaScript, Python and Rust. I reused the extractor from my Week 3 entry, Code Déjà Vu.
3. Decide who's really dead. This was the actual problem. Every edit leaves the old version of a still-living function behind, so "not at HEAD" would bury you in near-copies of code you still have. A function only counts as a ghost if:
- nothing with its name still lives in that file at HEAD (so it wasn't just edited),
- its exact body isn't anywhere at HEAD (so it wasn't moved),
- and it isn't alive at the tip of another branch.
In my smoke test, a deleted function is summoned, an edited one isn't, and one moved to another file isn't.
4. Search by meaning. Each ghost's last living version is embedded with EmbeddingGemma 2, cut to its first 256 Matryoshka dimensions; your description uses the model's task: code retrieval prompt. These are the settings I'd already tuned for Code Déjà Vu, and if its dejavu serve is running, Git Séance borrows the warm model so a summon takes 0.1 to 0.3 s instead of ~13 s.
Does it work?
My agent described 18 real deleted functions from four repos (three of mine and one open-source project), reading each one first. They came from a random sample, with trivial ones dropped and a few more picked by name. The eval script then checks where the right one ranked among 229 unique ghosts:
| right function first | in the top 5 | |
|---|---|---|
| Git Séance | 17/18 | 18/18 |
| Keyword matching (rank by query words found in the code) | 5/18 | 14/18 |
The one miss came second. Small set, small graveyard, descriptions written right after reading the code: a first measurement, not a benchmark.
Why Does Open Innovation Matter?
- The past is private. Deleted code is where the embarrassing stuff lives: the hack you're glad is gone, the config that once held a real key, the client's code you were never supposed to keep. Nobody should have to upload their whole history to a cloud API to search it. An open-weight model reads it locally, offline.
- Open tools compose. git's plumbing is open, tree-sitter is open, EmbeddingGemma 2 is open, and so is last week's project. Git Séance is mostly those four things plugged together, which is why it's about 220 lines and not 2,000.
- Open history is the point. git keeps everything because nothing is ever really gone in open source: someone, somewhere, can always check out an old commit. Git Séance just gives that memory a search box.
Prize Categories
- Best Use of Gemma: EmbeddingGemma 2 does all the searching, locally, with its Matryoshka-shrunk 256-dimension embeddings.
Top comments (0)