{"slug": "i-can-t-ask-my-old-team-lead-why-anymore-so-i-built-a-seance", "title": "I can't ask my old team lead why anymore, so I built a séance", "summary": "A developer built Ouija Blame, an open-source tool that traces a line of code back to the commit that first wrote it using git log -L, then gathers the author's and reviewers' written words from commits, pull requests, review comments, linked issues and recorded AI-agent prompts. A Gemma model selects passage numbers from a fixed list and answers only with verified, cited quotes, saying \"I never wrote down why\" when no reason exists. On 45 real lines that were deleted as pointless and later restored across Rails, Kubernetes, Home Assistant, Ansible and Istio, the tool surfaced a written reason for 28/45 lines versus 19/45 for the git blame message, though no method recovered the reason a line had to return more than 18% of the time.", "body_md": "*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).*\n\nA month ago my team lead left. He was the one who knew why our code is shaped the way it is: why one piece\n\nis split from another, why a check lives here and not there, why a decision that looks wrong was actually\n\nright. More than once since then I have hit one of those decisions, opened a chat to ask him, and stopped\n\nhalfway through typing. He has moved on. It felt wrong to pull him back into code he no longer owns, and\n\nthere was nobody else to ask.\n\n`git blame` did not help. It showed me the last person who touched the file, not the person who decided why\n\nit exists. That is when it hit me how much a team loses when one person walks out the door, and how little\n\nof what they knew was ever written down where the next person would find it.\n\nHalloween is about talking to people who are no longer in the room. So I built a séance for them.\n\n**TL;DR**\n\n**Ouija Blame** asks a line of code why it exists. It walks the line back to the commit that **first\nwrote it**, gathers what its author and reviewers wrote (commits, the pull request, review comments,\nlinked issues, and the prompts behind agent-written code), and the **ghost answers only in their own\nwords**, each one linked. If nobody ever wrote the reason down, the ghost says **\"I never wrote down why.\"**\n**Gemma can only point, then explain with citations.** The open model picks passage *numbers* from a\nfixed list, so it cannot put a word in the ghost's mouth, and code checks every quote word for word. Then\nit writes a plain-words answer (what the line does, why it exists, what to check before you change it)\nwhere every reason cites a quote by number.\n**The test:** 45 real lines from Rails, Kubernetes, Home Assistant, Ansible and Istio that someone deleted\nas pointless, which broke something and were put back. Every method saw only history from before the\ndeletion. The séance surfaced a written reason for **28/45** lines; the `git blame` message, **19/45**\n(+20 points, 95% CI +9 to +33). Reading the whole PR behind the blame commit found **29/45**, but meant\nreading **268 words** per line instead of **67**.\n**What surprised me:** no method, mine included, found the reason the line *had to come back* more than\n18% of the time. The reason code was written and the reason it must stay are usually different, and the\nsecond one is almost never written down.\n**What failed:** Gemma 4B hates silence. It said \"I never wrote down why\" for only 1 of the 13 lines where\nno method found any reason.\n\n**[Ouija Blame](https://ouija-blame.onrender.com)** is a pixel-art séance for one question: *why does this line exist?* It is a séance for people's lost knowledge in a repo, not a haunted terminal.\n\n`git log -L` follows the line back through every change to the\ncommit that first wrote it. `git blame` stops at the last change, which in my test set was the wrong\ncommit In that Kubernetes example, `git blame` on `cluster/addons/storage-class/openstack/default.yaml` shows a\n\ngroup-version bump by a different person. The ghost is **@jsafrane**, who wrote the file in 2016, and the\n\nanswer comes from his PR: *\"In previous versions of Kubernetes a PersistentVolumeClaim without a StorageClass annotation on these cloud platforms would be satisfied by manually-created PersistentVolume\nobjects…\"* Six years later someone deleted it as an OpenStack leftover, and existing Cinder volumes became\n\nCode written with an AI agent has a new kind of lost knowledge: the prompt. The engineer typed the reason\n\ninto a chat, and the commit says \"Canvas rce2\". [Entire](https://github.com/entireio/cli) records those\n\nsessions and publishes them next to the code as `refs/entire/checkpoints/…`. Ouija Blame reads them with\n\nplain git (no account needed), so the ghost can quote the human's own prompt:\n\n**Ask a line of code why it exists. The ghost of whoever wrote it answers, only in words they actually\nwrote.**\n\nLive: [https://ouija-blame.onrender.com](https://ouija-blame.onrender.com) · DEV Hacktoberfest 2026, Week 4: Ghost in the Machine\n\nEvery codebase has a line nobody dares delete, and the person who knew why it is there has left. `git blame` shows the last commit that touched the line, which is often a reformat. Ouija Blame walks the\nline back to the commit that first wrote it, gathers what its author and reviewers wrote (commit\nmessages, the pull request, review comments, linked issues, and agent-session prompts recorded with\nEntire), and lets an open-weight model, Gemma, point at the passages that say why. The model can only\nchoose passage numbers, never write the quote, and code checks every quote word for word against its\nsource. If nothing says why, the ghost says **\"I never wrote down**…\n\n```\nline ──git log -L──▶ every commit that touched it ──▶ PRs · reviews · linked issues · Entire prompts\n                                                              │\n                         passages: exact slices of the raw text (templates, bots, /lgtm dropped)\n                              │  BM25 against the line's own words → top 16\n                              ▼\n                      Gemma 3 4B (Ollama): \"which passages say WHY?\" → ids from an enum\n                              │\n                      quote checker: word for word in the source, or dropped\n                              ▼\n                      the ghost speaks, or \"I never wrote down why.\"\n```\n\n`enum`, so Gemma can only\nchoose from what is there, and every chosen passage is checked against its source again before it is\nshown. Over the 45 test séances the checker dropped `api.github.com`; the server asks the\nmedium. The same `seance.run()` serves the evaluation from a disk cache.\nThe hardest part of \"why does this line exist?\" is knowing the right answer. Big projects have a natural\n\nanswer key: **reverts of deletions.** Someone removes code that looks pointless, it breaks something, and a\n\nrevert puts it back, usually with a PR explaining why it was needed.\n\n`git log -S` hits for the line's main identifier; the séance.\n| Method | Gives the revert's reason | Gives a written reason (any) | Words to read (median) | \n|---|---|---|---|\n| `git blame` message | 7/45 (16%) | 19/45 (42%) | 12 | \n| blame + its whole PR | 7/45 (16%) | 29/45 (64%) | 268 | \n| `git log -S` , 5 oldest | 5/45 (11%) | 15/45 (33%) | 41 | \n| **séance** | **8/45 (18%)** | **28/45 (62%)** | **67** | \n\nPaired bootstrap over cases, séance minus baseline, any written reason: vs blame **+0.20 (+0.09 to +0.33)**,\n\nvs `log -S` **+0.29 (+0.13 to +0.44)**, vs blame + PR **−0.02 (−0.11 to +0.04)**. On the revert's reason the\n\ndifferences are all within ±0.09 and not significant.\n\nSo the honest summary: **the séance finds a written reason far more often than blame, about as often as reading the entire PR, in a quarter of the reading**, and it reaches the original author every time.\n\nEvery number above comes from `python -I scripts/stats.py`, which reads only files in\n\n[`results/`](https://github.com/Tanay3484/ouija-blame/tree/main/results).\n\nThe first real user was me. I opened a haunted line from the gallery, read through the séance, and my honest\n\nreaction was: *\"all I see is a git blame.\"* The quotes were all there, but nothing told me in plain words the\n\none thing I had come for. That sentence changed the product the same night: every séance now opens with an\n\nanswer card (what the line does, why it exists, what to check before you change it), and every reason on\n\nit is pinned to the quote it came from, so you can check the medium against the ghost.\n\nThe ghosts in the gallery are real people who wrote real code, and most of them simply moved on to other\n\nwork. Nobody here is framed as dead, the ghost is a generic sprite rather than anyone's photo, and every word\n\nit says links to where that person actually wrote it. That last rule turned out to be the whole product:\n\na tool that only lets people speak in their own recorded words is a tool that makes you notice how rarely\n\nwe write down *why*.\n\nThis week I was buried in work until the last night, so most of the code was written by Claude Code from\n\nspecs we agreed on (`specs/` in the repo). I chose the idea, the cuts and the evaluation design, and I was\n\nits first user.\n\n`render.yaml`. The AI runtime is on Render.` Entire-Checkpoint` trailer, Ouija Blame reads\nthe published checkpoint and the ghost quotes the developer's own prompt (see the agent-written séance in\nthe gallery).", "url": "https://wpnews.pro/news/i-can-t-ask-my-old-team-lead-why-anymore-so-i-built-a-seance", "canonical_source": "https://dev.to/tanay_singh_1005/i-cant-ask-my-old-team-lead-why-anymore-so-i-built-a-seance-3ih2", "published_at": "2026-10-31 05:06:43+00:00", "updated_at": "2026-10-31 05:19:49.680293+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools", "large-language-models", "ai-agents"], "entities": ["Ouija Blame", "Gemma", "Kubernetes", "Rails", "Home Assistant", "Ansible", "Istio", "Entire"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/i-can-t-ask-my-old-team-lead-why-anymore-so-i-built-a-seance", "markdown": "https://wpnews.pro/news/i-can-t-ask-my-old-team-lead-why-anymore-so-i-built-a-seance.md", "text": "https://wpnews.pro/news/i-can-t-ask-my-old-team-lead-why-anymore-so-i-built-a-seance.txt", "jsonld": "https://wpnews.pro/news/i-can-t-ask-my-old-team-lead-why-anymore-so-i-built-a-seance.jsonld"}}