跳到正文
DEV Community· Manthan Gupta·· 2 小時前AI 評分34

Necropsy:以開源 AI 剖析 Git 儲存庫歷史

Necropsy

AI 導讀

Necropsy 可分析已停止維護的 Git 儲存庫,並按指定日期與用戶對話,回答只引用當時已存在的提交。工具以 Ollama 本地執行開放權重 Qwen3,並用提交資料計算統計數字;驗證程式會移除缺乏證據支持的説法。索引及提問毋須使用 API,初次下載模型後亦可離線使用。

正文

Manthan Gupta

Hacktoberfest Open-Source AI Challenge: Ghost in the Machine Submission 👻🌼

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine

What I Built

Every abandoned repository is a ghost. Someone's decisions are still in there, along with their abandoned ideas and a last commit that reads like a final breath, but nobody can talk to it.

Necropsy performs an autopsy on a dead Git repository and then lets you hold a séance with it.

  • The autopsy finds the time of death, the last-gasp commit, the activity curve, the bus factor, and the project's "eras". Its graveyard lists tombstones for deleted files and functions, each carrying the deleting commit's message as its epitaph.
  • The séance is a chat with the project's ghost. You drag a time slider to any date in the project's life, and the ghost knows only what existed on that date. Every claim it makes cites real commits, and a verifier removes any claim it can't back up. When the evidence isn't there, it answers: "The dead do not remember that."

I took "Ghost in the Machine" literally: a ghost made of a machine's own memory. A repository is a recorded history of someone's mind, and I wanted to make it answerable without letting it make things up.

Code

The most important idea in the project fits in two lines:

n = bisect_right(item_dates, as_of_end)   # commit dates sorted ascending
scores = vectors[:n] @ query_vec          # later commits are not in this slice

Commit embeddings are stored sorted by date, so "everything up to the chosen date" is a prefix of the list. Commits after that date are never scored, so they can't influence which evidence comes back. Filtering after ranking would let the future leak into the past.

How I Built It

Open-source AI in the core:

  • Ghost model: an open-weight Qwen3 model ([EDIT: confirm the exact tag you ran, e.g. qwen3:8b, and your fallback]) served locally by Ollama. It writes the ghost's answers as structured JSON: an answer plus a list of claims, each with commit hashes.
  • Embeddings: BAAI/bge-small-en-v1.5 runs in-process through sentence-transformers. It powers retrieval, the verifier's support check, and the clustering behind the project's "eras". It's small enough to run on a CPU.
  • Everything else is ordinary, auditable code: PyDriller reads the Git history, tree-sitter finds deleted functions, SQLite stores it all in one file, scikit-learn and UMAP cluster the eras, FastAPI serves the API, and a static HTML/JS frontend with D3 draws the charts and the time slider. There's no framework build step and no CDN.

Why it's more than a chatbot over a repo:

  1. The time axis is the product. The date filter is structural (the prefix slice above), and a mandatory automated test builds a fixture repo with known dates and checks that nothing newer than the chosen date reaches retrieval, the prompt, the graveyard, or the statistics.
  2. The ghost has to show its evidence. The verifier is plain code, not another model. It checks that each cited commit exists, is dated before the chosen date, was in the evidence the model was shown, and is semantically close to the claim. Small local models cite things that don't exist, so unsupported claims are deleted.
  3. Numbers never come from the LLM. Time of death, decline onset and bus factor are formulas over commit data, so they're reproducible. The model explains them but never computes them.
  4. Eras are display-only. Clusters are computed from the whole history, so they depend on the future. Their labels never enter the ghost's context.
  5. The ghost speaks as the project, not as a person. It quotes real commit messages verbatim and never impersonates a named maintainer.

[EDIT: describe what actually works at submission time, and list anything still planned. Judges can tell.]

Why Does Open Innovation Matter?

Necropsy exists because of what a closed API makes impossible.

  • Dead private repos. The projects most worth autopsying are often old company code or unreleased side projects. They can't be pasted into a hosted service. With local inference they never leave the machine.
  • It costs nothing to run. Indexing thousands of commits and asking unlimited questions costs electricity, not API credits. An autopsy that you'd think twice about running if it cost per query becomes something you run on every repo.
  • Offline. After the initial clone and one-time model downloads, you can unplug the network and keep working.
  • Reproducibility and preservation. This one is personal to the theme. A tool about preserving history shouldn't depend on a model that gets quietly updated or retired. Pinned open weights mean an autopsy produced today can be reproduced years from now.
  • The model is a replaceable part. Swapping an 8B model for a 4B one is a one-line config change. [EDIT: if your eval harness ran, add one real sentence on what the comparison showed. Don't invent numbers.]

A hosted model would give me a nicer answer on a good day. It couldn't give me privacy, an offline demo, or an answer that can be reproduced next year.

My Agent Session

I gave the agent the product, technical and architecture documents and an AGENTS.md of non-negotiables, such as the time-travel invariant, verified citations, and no closed APIs, so it built against a spec instead of improvising. [EDIT: confirm this is what you did.]

The Spirit of It

I pointed Necropsy at [your abandoned project], dragged the slider back to [month/year], and asked [your question]. It answered [what it said], and cited [the commit]. I had forgotten [what you'd forgotten].

來源:DEV Community · dev.to