grave:為電腦上每個已終止的程序寫下墓誌銘
grave: I Gave Every Dead Process on My Machine an Epitaph
grave 以 C++ 編寫,會監察它啟動的程序;程序異常終止時,便把退出狀態、訊號、記憶體用量及標準錯誤等事實交給本機 Gemma 生成墓誌銘。它透過 Ollama 使用 Gemma 3 4B,並把事實與墓誌銘分開儲存,讓用戶可核對模型輸出。示範可在 Wi-Fi 關閉時運行,資料不會離開電腦,亦無需按每次終止付費。
This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine
What I Built
Programs die on my machine constantly and nobody notices. A segfault scrolls off the screen. A kill goes through. The only record is a number in $? that I will never look at again.
So I built grave, a small wrapper that treats those deaths as worth remembering.
grave ./myprogram
If the program exits cleanly, grave says nothing. If it dies, a local Gemma model writes its epitaph using only the facts of its death. Then you can hold a séance:
grave seance "who killed you?"
The most recent ghost answers from its own record. If the record doesn't say, it's supposed to admit it doesn't remember.
It's 99 lines of C++ and does one thing.
Demo
VIDEO_LINK_HERE
The video is recorded with the Wi-Fi off. First a segfault, then the séance:
$ ./grave ./crash
OUTPUT_1_HERE
$ ./grave seance "who killed you?"
OUTPUT_2_HERE
Code
REPO_URL_HERE
How I Built It
The wrapper forks and execs your command, pipes its stderr to keep its last words, and calls wait4 for the exit status, the killing signal, and peak memory. A clean exit is silent. Anything else becomes a fact sheet: name, seconds alive, exit code or signal, peak memory, last words.
The fact sheet goes to Gemma (gemma3:4b) through Ollama with one rule:
Write a 3 sentence epitaph for a dead process. Use ONLY these facts. Do not invent a cause of death or any detail not listed.
One design decision came from testing. My first version stored the epitaphs in the same file the séance reads. That means a hallucinated epitaph would later be quoted back as fact. So the graveyard (~/.graveyard) holds facts only, epitaphs live in a separate file (~/.graveyard.epitaphs), and the séance only ever sees the facts of the most recent death.
Limits. A 4B model can still embellish no matter what the prompt says. That's why the facts and the epitaphs are kept in separate files: you can always check what the model was told against what it wrote. grave also only sees what it launches, not every death on the system. And a process's stderr goes straight into the prompt, so a hostile program could write instructions into its own last words. The exit status prints first and the epitaph follows, because a local model on a laptop is not instant.
Why Does Open Innovation Matter?
A dead process's last words are rarely harmless. They carry file paths, usernames, hostnames, and half a stack trace. I wasn't willing to send that to a server I don't control just to get a sad sentence back.
With an open-weight model, the demo runs with the Wi-Fi off, which the video shows. Nothing leaves the machine, and it costs nothing per death. Swapping models is one environment variable, GRAVE_MODEL, so when a better small model ships, nothing in the code changes.
A closed API could write the same epitaph. It couldn't do it offline, privately, and for free.
The Spirit of It
The first thing I buried was a program I wrote to crash on purpose. It allocated 50 MB, touched every page, then dereferenced a null pointer. I knew exactly how it would die, and I still read the epitaph like it was news.
This is what came back:
EPITAPH_HERE
Then I asked the dead process who killed it. It could only answer from its record, and the record says one thing: signal 11, a segmentation fault. No murderer, just a pointer that pointed nowhere.
That's what stuck with me. Every crash I've ever had was this specific and this unremarkable, and I scrolled past all of them. Something should at least say a few words.
Prize Categories
Best Use of Gemma
來源:DEV Community · dev.to