DEV Community

Cover image for Every Codebase Has a '// DO NOT TOUCH' File. I Built an AI Necromancer to Summon the Ghost of the Developer Who Wrote It 💀🔮

Every Codebase Has a '// DO NOT TOUCH' File. I Built an AI Necromancer to Summon the Ghost of the Developer Who Wrote It 💀🔮

Dhruv Jani on October 31, 2026

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine What I Built "Every codebase has ghos...
Collapse
 
dj29 profile image
Dhruv Jani •

💀 Every developer has that one file they're afraid to touch.

You know the one. No documentation, questionable logic, three mysterious comments, and absolutely nobody remembers why it works.

That's the problem I wanted to tackle with GitSéance. Instead of blindly refactoring legacy code, what if we could actually ask the original developer why they wrote it that way?

So I built an AI necromancer with specialized agents, Git history analysis, TabPFN, Gemma, and even a voice for the ghosts. 👻

Now I need to know: What's the most terrifying // DO NOT TOUCH file you've encountered? And more importantly, did you ever dare to touch it? 😂

Collapse
 
francistrdev profile image
FrancisTRᴅᴇᴠ •

Very great stuff Dhruv! Thanks for reminding me!

There is actually an interesting video on how local AI is not really "private" in a way.

It's something I found recently. Not wanting to contradict on what you mention on your first point on "Why Innovation Matters", but it's something I found recently that surprised me when we think local AI is completely offline, which is not entirely true.

Otherwise, great work Dhruv!! :D

Picked as gem
Collapse
 
dj29 profile image
Dhruv Jani • • Edited

Thanks for the compliments and info, I really never thought of local models from this P.O.V.

Yeah its about running someone else's file and you need to make sure it behaves like you want it to!

And I gave you gem just for fun, I had it since 2 days and was annoying me on every comment I read, like oh I haven't given it to someone.😅
Have A Great Day!

Collapse
 
nullandvoid_ profile image
Jyanthi •

A truly ingenious idea! Code often outlives its creators, but the reasoning behind it gets lost. I particularly admire how you've used Git history to recover that forgotten wisdom rather than simply dismissing old code as technical debt. Understanding the past is often the key to improving the future. Thank you for sharing!

Collapse
 
evgeniikonev profile image
Evgenii Konev •

Cool project, reaper part is really useful.

But from my experience, "do not touch" files usually appear not because developer left. Team decided one way, after one month code was written other way, and nobody wrote which decision is current. So séance is more like fixing the result, not the reason.

In our project we keep all decisions in markdown files near the code (ADR and stories), agents also read it and update. We call it ProjectStore. Boring, but later nobody need to call ghosts :)

Question: reaper reads commit messages or PR descriptions? Usually only there you can find "why".

Collapse
 
dj29 profile image
Dhruv Jani •

100% agree on ADRs! If every team maintained clean markdown decision records like your ProjectStore near the code, software engineering would be paradise and we wouldn't need code necromancy at all! 😄

GitSéance was designed for the messy reality of the other 90% of codebases — especially ancient open-source fossils from 2010 where no ADRs exist and the original creators moved on a decade ago.

To answer your question: right now, the Reaper reads commit messages, not PR descriptions.

It traverses the Git commit log for each file to:

  1. Detect fear keywords in commit messages (hack, temporary, black magic, workaround).
  2. Calculate the bug-fix ratio (flagging commits with fix, patch, bug).
  3. Pass the last 10 commit messages + timestamps + authors directly to Gemma as context to reconstruct the "why".

The main reason I didn't query PR descriptions in v1 was strictly GitHub API rate limits (unauthenticated REST calls cap out at 60 req/hr, and querying PRs per file across a whole repo burns through that instantly).

That said, querying linked PR descriptions and review discussions when an authenticated GitHub PAT is provided is a fantastic idea for v2. Appreciate the great insight! 💀

Also, I'd love to continue this project once its out of judging.

Have A Great Day!

Collapse
 
evgeniikonev profile image
Evgenii Konev •

Yes, agree, most of real code is fossils without any docs :) For old projects your way is the only way.

Small tip for v2: in GitHub GraphQL commit has field associatedPullRequests, so you can get PR description together with commit history in one query, not one request per file. It needs token, but limit is much bigger.

Good luck with judging, will follow the project!

Thread Thread
 
dj29 profile image
Dhruv Jani •

Thanks Sir! for the tips and wishes.

Have A Great Day!

Collapse
 
alexcodebytes profile image
Oleksandr •

The thought-token parsing for Gemma is a really clever fix. I've run into the same issue with reasoning models — the internal chain-of-thought eats the output budget. Your _extract_text walker is a clean solution. Did you find that the thought tokens were consistent enough to filter reliably, or did you need fallbacks for edge cases?

Collapse
 
dj29 profile image
Dhruv Jani •

Great question! The short answer is: part.thought = True in the google-genai SDK is consistent, but token budget starvation was the sneaky edge case.

Here is what we ran into:

  1. The Chain-of-Thought Trap: If max_output_tokens was set too tight (e.g. ~300 tokens), Gemma would spend its entire budget in internal reasoning mode. The call would return FINISH_REASON_MAX_TOKENS, but every single part had thought = True. Filtering them left us with an empty string! Bumping the budget to 1024+ gave it enough runway to conclude its thought and emit dialogue.

  2. The Multi-Tiered Fallback: In _extract_text, we intentionally check candidate.content.parts first (filtering thought=True), and fall back to response.text second (in case future SDK versions or other endpoints don't expose separate part objects).

  3. App-Level Graceful Degradation: If the model returns empty text anyway (or hits a rate limit / 404 on an obscure repo), the backend catches it and serves a deterministic forensic fallback persona based on the Git commit blame metadata. That way the CRT terminal never crashes with an unhandled exception.

Really appreciate you looking at my code! Did you find a similar workaround with your reasoning models?

Collapse
 
alexcodebytes profile image
Oleksandr •

The 'token budget starvation' edge case is exactly the kind of thing that only shows up in production. Setting max_output_tokens to 300 seems reasonable until you realize the model spends all of it thinking and never gets to the actual response. Bumping to 1024+ is the right fix, but it's a non-obvious one.

Thread Thread
 
dj29 profile image
Dhruv Jani •

Exactly! When your API call returns 200 OK and charges you for 300 tokens, but the text payload is completely empty, it literally feels like a ghost in the machine. 👻😅

Hopefully future SDKs decouple the reasoning budget from the completion budget so developers don't have to learn this the hard way. Really glad you found the post-mortem useful! 🤝

Thread Thread
 
alexcodebytes profile image
Oleksandr •

The 'feels like a ghost in the machine' is the perfect description. You pay for 300 tokens, get an empty string, and the only thing haunting you is the API bill. Very on-theme for this project.

Thread Thread
 
dj29 profile image
Dhruv Jani •

Yeah Yeah, different kind of horror and you don't even need halloween to vibe with it.😂
Have A Great Day!

Collapse
 
anas_issath profile image
Anas Issath •

“I left that hack at 2 AM before a release. I promised myself I would refactor it that weekend, but that weekend never came” is the most relatable thing a ghost has ever said. Love the shift from fearing legacy code to honoring the person who wrote it. The death certificate is a brilliant touch too.

Collapse
 
dj29 profile image
Dhruv Jani •

Thanks!
The whole motive was to bring out ghost of one who wrote file and honor them, and if you want have a voiceover using eleven labs api voice key.
Glad you liked it!
Have A Great Day!

Collapse
 
gautamtalksdev profile image
Gautam K •

Fun build. One thing I'd change before v2: the ghost speaks in first person as a real, named developer, and in your own example it "confesses" to leaving a 2 AM hack before a release. That's a quote the model made up, attributed to a real person, about their professional work. If someone screenshots it, it reads like Thadeus said it. A small label on every ghost line ("generated from commit history, not the author's words"), or using the role instead of the name, would keep the fun and remove the risk.

Collapse
 
dj29 profile image
Dhruv Jani •

Thanks Sir,
I'll add the disclaimer once the results are announced!

Have A Great Day!

Collapse
 
paullovelace profile image
Paul Lovelace •

I have that file. Everyone has that file, and the 'nobody knows why this works' comment is always written by someone who left three years ago. The ghost-chat idea is fun, but the part I'd actually use is the mortality badge — a README that admits which files are haunted feels more honest than pretending the repo is healthy. Did the TabPFN score surprise you on any file you thought was fine?

Collapse
 
dj29 profile image
Dhruv Jani •

Haha completely agree — the README badge that actually admits the skeletons in the closet is much more honest than a wall of fake green badges! 💀

To answer your question: yes! That was actually the exact reason I used TabPFN over a naive heuristic/linter.

A simple rule-based linter looks at a core mathematical utility (like crc32.py or slugify.py untouched for 3+ years) and blindly screams "DEAD". But TabPFN evaluated the high test sentinel and near-zero defect churn, correctly predicting it was just stable/frozen (18% mortality).

The real surprise in the other direction was files untouched for only ~6 months that looked "alive" on the surface, but had 100% author turnover and a 60%+ bug-fix commit ratio — TabPFN immediately flagged them with 78%+ mortality risk. It caught silent structural rot before anyone realized the original architect had vanished.

Thanks for checking out the project!

Collapse
 
madhabcoder profile image
Nilamadhab Senapati •

Every team has that file, and the ghost is usually still on the team, just too scared to admit they wrote it. Using commit history and author turnover to score "file mortality" is a genuinely useful idea hiding inside a very fun Halloween costume.

Collapse
 
sherotree profile image
Sherotree •

Love that the Reaper walks commit history and fear comments before the Medium speaks — most “explain this legacy file” tools skip the forensic step and just invent intent. TabPFN as the mortality scorer is a neat non-LLM choice for that risk vector too.

Collapse
 
dj29 profile image
Dhruv Jani •

Thanks! Glad you liked it!
And I'm glad that people got the feel of haloween.😅
Have A Great Day!

Collapse
 
tomzafred profile image
Tom Zafred •

The CRT terminal aesthetic is fantastic, but you have stumbled onto what is quietly the single most dangerous failure mode in autonomous coding today: the "Aesthetic Refactoring Trap".

Every // DO NOT TOUCH comment in a legacy system is essentially an unwritten tombstone for an undocumented edge case. Someone spent three days in 2018 tracing a race condition, a weird hardware driver timing quirk, or an undocumented vendor API payload, hacked together an ugly fix, and left it there because it worked.

When an LLM coding agent encounters that file, its attention mechanism naturally prioritises structural cleanliness. It sees an unrolled loop, a redundant-looking null check, or a manual delay and immediately attempts to "modernise" it. The moment it cleans the code, the subterranean bug wakes back up.

Here is the architectural gem your Necromancer can unlock: don't just ask the ghost why the hack exists; ask the ghost to write the Negative Invariant Test.

In production systems, asking an author persona "What does this code do?" usually yields a polite, generic explanation. But if you prompt the Necromancer with:
"Look at the commit diff where I introduced this ugly workaround. What exact input, race condition, or sequence of events will cause production to crash if someone simplifies line 42?"

Now the ghost isn't just giving you spooky lore. It gives you the concrete failure condition that you can turn into an executable regression test. If the test passes on the ugly legacy code and fails on the clean refactored code, the file is no longer haunted - it is formally verified.

Moving from code archaeology to automated negative constraint extraction is where tools like this become genuine enterprise defence-in-depth. Brilliant build, Dhruv.

Collapse
 
dj29 profile image
Dhruv Jani •

Thanks Sir!
I'm definitely taking all the suggestions and will try to continue this project once I' done with my college exams.
Have A Great Day!

Collapse
 
emilywoodsnyc profile image
Emily Woods •

The flask-cache example makes me want a behavior check beside the revival blueprint. I'd ask the agent to write down which cache semantics must survive, then run a short access sequence against both versions before replacing anything. This cache review exercise gives a manageable version of that: a plausible rewrite can still change eviction or tie-breaking. Could GitSéance attach suggested characterization tests to a blueprint, with the assumptions marked for review?

Collapse
 
dj29 profile image
Dhruv Jani •

Characterization tests (Golden Master testing) are a fantastic idea! When you're refactoring 15-year-old code, verifying behavioral parity (cache eviction, TTL tie-breaking) before touching a line is critical.

Right now, GitSéance's Revival Blueprint focuses on the forensic architectural roadmap (e.g. migrating setup.py packaging to modern declarative build tools and surfacing CVE-free drop-in replacements).

Having the Medium agent generate an automated characterization test harness alongside the blueprint so engineers can verify invariants before refactoring would be a killer feature for v2! 💀

But will have to wait till judging for this week is completed!
Have A Great Day!

Collapse
 
salparvez profile image
Sal Parvez | ML Systems RI •

Every old house has a DO NOT TOUCH wall too, usually the one where somebody notched a joist decades ago. I'd want the ghost's answers tied to actual commits so you can tell what's grounded from what's a guess.

Collapse
 
dj29 profile image
Dhruv Jani •

Bruh, it already does that, you didn't read the post.

Collapse
 
peter7865 profile image
Peter •

Reading through old codebases always feels like stumbling through a digital graveyard. Projects like this make legacy debugging a lot more fun. Over on the engineering and packaging side at The Printing World, we deal with plenty of old automation scripts that nobody wants to touch, so I definitely appreciate a good automated post-mortem tool

Collapse
 
yug_vasava profile image
Yug Vasava •

Nice bro, I tried it!

AND STOP GRINDING TOO MUCH!!!

Collapse
 
dj29 profile image
Dhruv Jani •

Thanks bro
and a what now?👂

Collapse
 
yug_vasava profile image
Yug Vasava •

😂 Great! see you soon

Thread Thread
 
dj29 profile image
Dhruv Jani •

Sure!

Thread Thread
 
yug_vasava profile image
Yug Vasava •

After Diwali right?

Thread Thread
 
dj29 profile image
Dhruv Jani •

Yep! Straight for externals!😄

Collapse
 
botsailorofficial profile image
BotSailor •

This is such a creative way to tackle one of the most familiar problems in software development. Every codebase seems to have that one file nobody wants to touch because its original logic and history have slowly become a mystery.

I especially like the idea of using AI to bring some of that hidden context back instead of simply trying to rewrite everything. Understanding why a particular piece of code was written that way can be just as important as understanding what it does. Sometimes the biggest challenge isn't fixing legacy code, but figuring out the story behind it. Great concept!

Collapse
 
mp3sss31 profile image
mp3sss •

Really like that the pipeline starts from signals most tools ignore — commit-history orphan detection plus the human traces ('hack', 'do not touch' comments) rather than static analysis alone, because fear comments are genuinely high-signal metadata about where knowledge died. The four-agent split is the right decomposition: finding, predicting, translating and proposing are different jobs that shouldn't share one prompt. In desktop app maintenance I'd point this at the one mysterious native module nobody dares rebuild — grounding the 'ghost' in git blame and release history makes the revival blueprint auditable instead of hallucinated.

Collapse
 
dj29 profile image
Dhruv Jani •

Thanks! That exact point — that a single mega-prompt hallucinates while 4 grounded agents keep each other honest — was the core design philosophy behind GitSéance. Appreciate you highlighting the architecture! 💀

Have A Great Day!

Collapse
 
kling4ai-production profile image
Kling4 AI •

Extracting historical intent from git blame and PR discussions is surprisingly useful for legacy modules. Most teams just let tribal knowledge evaporate.

Collapse
 
marko_kseppnen_6250a7f profile image
Mr Smithnen •

Wow hah, looks cool 🫨🤪😛

Hmm, I will need to investigate further if and how I can run this 😋

Collapse
 
dj29 profile image
Dhruv Jani •

It's deployed and live Sir.
gitseance.onrender.com/
And there are sample repositories already there you can just select one to try it😅

Collapse
 
hammiwor profile image
hammi •

the '// DO NOT TOUCH' file is so real. every repo i've ever joined has one and nobody admits who wrote it lol. great read

Collapse
 
technogamerz profile image
𝐓𝐡𝐞 𝐋𝐚𝐳𝐲 𝐆𝐢𝐫𝐥 •

Cool ☠️

Collapse
 
dj29 profile image
Dhruv Jani •

Thanks di!!!

I'd love if you try it.

Have A Great Day!

Collapse
 
technogamerz profile image
𝐓𝐡𝐞 𝐋𝐚𝐳𝐲 𝐆𝐢𝐫𝐥 •

Good luck!

Collapse
 
dj29 profile image
Dhruv Jani •

Thanks Di😄

Collapse
 
kigster profile image
Konstantin Gredeskoul • • Edited

I disagree with your premise.

I believe that most of the time it's not a file in the middle of your codebase that people don't know how it works, but it's the file that's written in a different language, like it's a build file written in Bazel or Makefile.

And you don't really have any real programmers who know or remember how to write those. So someone freaks out and puts that comment: "Do not touch, we don't know how this works."

I would feel ashamed to come home and still
feel like I'm a programmer if I ever did that. Plus, today you can always ask AI what the hell is the logic inside and how does it work? So, no, I don't buy that. I don't buy that for a second.

Although, on the other hand, when applied to this particular website, dev.to, i might be willing to agree that it runs on a whole bunch of files like that in the codebase. I think it might suffer from exactly // DO NOT TOUCH OR IT WILL BREAK // type of file because: when I briefly switched to a different app for like a second, and then came back, this site decided to auto refresh and my carefully crafted professionally written comment disappeared like Thanos snapped his fat fingers.

And so, this is the second time I'm writing it, and I am more pissed than I was when I first read the post. I am glad you won an award, dont get me wrong. I am just appalled that such slop written by humans exist. Thank God moving forward AI will write most of our code.

I bet they won't be leaving such comments unless they are encrypted messages for other agents.

hallelujah!

Collapse
 
alexshev profile image
Alex Shev •

The useful output is not a fictional author narrative; it is a traceable map of what makes the file risky to change. I’d surface the evidence beside every explanation—recent callers, ownership churn, test coverage, and dependency edges—so the recommendation can be challenged before anyone treats it as repository truth.

Collapse
 
dj29 profile image
Dhruv Jani •

That's actually the exact architecture under the hood!

The ghost persona is the creative interface layer built specifically to honor the Hacktoberfest "Ghost in the Machine" (Halloween & Día de los Muertos) challenge theme. But you can't revive legacy systems on vibes alone.

Underneath the séance altar, that exact traceable evidence is computed across our 7-dimensional forensic feature vector:

  • Ownership churn (unique_authors bus factor calculation)
  • Test coverage sentinels (has_tests branch presence)
  • Defect density & change risk (bug_fix_commit_ratio and churn_velocity)
  • Temporal decay (days_since_last_commit and lines added/deleted ratio)

That's why we added the "📊 Export CSV" button and the native Model Context Protocol (MCP) server — so engineers can audit the raw telemetry, challenge the Bayesian mortality probability, or feed the tabular distribution directly into their own CI/CD pipelines.

Best of both worlds: grounded forensic telemetry for the codebase, wrapped in an authentic retro persona for the hackathon spirit! 💀Spot on analysis — and that's actually the exact architecture under the hood!

The ghost persona is the creative interface layer built specifically to honor the Hacktoberfest "Ghost in the Machine" (Halloween & Día de los Muertos) challenge theme. But you can't revive legacy systems on vibes alone.

Underneath the séance altar, that exact traceable evidence is computed across our 7-dimensional forensic feature vector:

  • Ownership churn (unique_authors bus factor calculation)
  • Test coverage sentinels (has_tests branch presence)
  • Defect density & change risk (bug_fix_commit_ratio and churn_velocity)
  • Temporal decay (days_since_last_commit and lines added/deleted ratio)

That's why we added the "📊 Export CSV" button and the native Model Context Protocol (MCP) server — so engineers can audit the raw telemetry, challenge the Bayesian mortality probability, or feed the tabular distribution directly into their own CI/CD pipelines.

Best of both worlds: grounded forensic telemetry for the codebase, wrapped in an authentic retro persona for the hackathon spirit! 💀

Collapse
 
deanlee profile image
Dean Lee •

Balancing churn velocity against defect ratios is the right fix for survival analysis on legacy files. Simple staleness heuristics consistently misclassify hardened utilities as dead weight because they treat elapsed time as decay. When test coverage is high and bug-fix frequency is near zero, an untouched module is usually closer to a stable asset than an abandoned liability.

Collapse
 
dj29 profile image
Dhruv Jani •

Couldn't have said it better myself! "Stable asset vs. abandoned liability" was the exact principle behind moving to the 7D Bayesian model. Appreciate the great takeaway, Dean! 💀

Have A Great Day!

Collapse
 
kling4ai-production profile image
Kling4 AI •

Extracting historical Git blame context and commit messages to reconstruct the original developer intent behind undocumented legacy files is genuinely useful. Most of those warning comments exist because of subtle edge cases or third-party quirks that were never documented anywhere else.

Collapse
 
aheadkit profile image
AheadKit •

Every codebase I've touched has that one file where the comments read like a restraining order. My rule has become: if the original author wrote DO NOT TOUCH in caps, they knew something they couldn't explain, and the séance idea is honestly the first respectful way I've seen to ask it questions before touching anything. Does GitSéance ever answer 'even I don't know, good luck'? Because that's what the real ghost would say.

Collapse
 
mudassirworks profile image
Mudassir Khan •

the Reaper agent flagging files from commit history and fear comments is the useful bit, and the 7 dimension vector feeding TabPFN is where i would push. mortality risk needs a ground truth label, and in most repos the file nobody touched for years is stable, not dying.

we scored staleness on a few repos and the rarely edited files with the most inbound imports were the safe ones, churn plus test coverage told us more than age.

what did you use as the label for calibrating the risk score, or is it unsupervised?

Collapse
 
erdenetsogt profile image
Эрдэнэцогт Амгаланбаатар •

hello

Collapse
 
peter7865 profile image
Peter •

We have legacy print automation scripts at The Printing World that nobody dares touch. Summoning the original dev to explain their 2 AM hacks would save us hours of guesswork on the warehouse floor.

Collapse
 
jovojovi profile image
jiovanny adel •
Collapse
 
minglai_lai_0ca58fef9df12 profile image
Edward Walton •

The ghost chat is a fun touch 😄 Does it link explanations back to specific commits or comments? I’d love to see what the history actually tells us versus what the ghost is piecing together.