Ghost Threads
Offline Gemma + TabPFN 0 API Keys
Local audit / no cloud

47 things I said I'd do.
I did none of them.

A small offline script that digests your private chat exports, spots promises that vanished into thin air, and gives each restless line an ofrenda.

Bhoot dikhao Zero cloud calls. Runs entirely on your machine.
412d
Oldest ghost found
412 days, 14 hours, 28 minutes cold

"I'll review the pull request before midnight." A message from 412 days ago with zero commits that night.

Origin

The night it started

It was 2am on a rainy Tuesday in [TODO: your city or room]. I was searching through [TODO: chat name or friend] for a link someone had sent me months ago.

Instead of the link, I kept bumping into my own words: "will review tonight", "sending the draft by afternoon", "call you in ten minutes".

Nobody was mad. No one followed up. The conversations simply kept moving until the promises evaporated into polite static.

That quiet decay felt worse than an actual argument. So I pulled my wifi, dumped two years of text logs onto my drive, and built a scanner to hold myself to account.

Interactive Altar

Restless spirits from my archive

Incense burning • Ghost eyes softly track your cursor
Ghost Birth Séance // Archive Replay
Spinning clock: Day 0 to Day 412...

Maafi-nama // Honest Apology Draft Target: Alex
Hey Alex, I found this message from 412 days ago where I said I'd review your PR. Obviously I never did, and you had to merge it yourself. I'm sorry for dropping the ball. Sending this so the ghost leaves me alone.
Send this directly on WhatsApp or chat to settle the conversational debt.
Mukti Pramaan Patra Record #0047

"I'll review the pull request before midnight."

Haunted this ledger for 412 days. Diya lit on the altar. Debt marked as forgiven.

Status: Mukti Prapt (Released)
# Terminal execution on local machine (wifi disconnected)
$ python ghost_threads.py --source ./chats/2024-export.txt --ollama-host localhost:11434
[02:14:02] Loaded 32,840 lines from local disk. Zero packets emitted.
[02:14:05] Connecting to Ollama (gemma2:2b weights loaded in RAM: 2.1GB)...
[02:14:09] [PROMISE_DETECTED] index: 4819 | sender: "me"
  verbatim: "I'll review the pull request before midnight."
  temporal_anchor: "before midnight"
[02:14:10] Running TabPFN tabular classifier against follow-up logs...
  timestamp_gap: 412.3 days
  resolution_signal_found: False
  ghost_verdict: RESTLESS_SPIRIT (rank #1 / 47)
[02:14:12] [DONE] 47 ghosts materialized on local altar.

Drop your chat export file here

Drag and drop any raw WhatsApp, Signal, or text chat export (.txt). It parses right inside your browser memory with zero network requests.

Test a promise you made recently

Type a commitment you told someone this week. See how local Gemma tags it.

Hisaab-kitaab

Anatomy of the 47 unkept promises

Accumulated Conversational Debt
8,554 days

The combined time these 47 ghosts have lingered in the archive since the original promises were made without follow-through.

62%
"Kal pakka" delays

Short-term postponements meant to buy 24 hours of peace that quietly turned into permanent radio silence.

24%
"Weekend pe pakka"

Vague social commitments made under mild social pressure, forgotten before Saturday morning arrived.

14%
"Checking this right now"

Messages typed while opening an email tab, instantly derailed by an incoming Slack notification.

Architecture

The path from raw chat export to resting spirit

Step 01

Local archive intake

Drop plain text or JSON exports straight from Signal, Telegram, or WhatsApp into a local folder. No tokenization on remote servers, no telemetry, and no sign-up forms.

Step 02

Gemma semantic filter

Gemma runs through Ollama on your machine. It extracts temporal commitments like "tomorrow morning", "kal sham tak", or "by end of day" across messy conversational contexts.

Step 03

TabPFN ghost scorer

TabPFN processes the extracted signals alongside conversation timestamp gaps. It performs in-context classification instantly on small tabular slices without requiring model fine-tuning.

Step 04

The ofrenda ledger

Unkept commitments are sorted by days elapsed. You get a clear list of what you abandoned so you can either finish the task or send an honest apology and let the ghost rest.

Philosophy

Why this refuses to be a cloud service

01 / Privacy

Chat exports are too intimate for someone else's server

These files hold five years of doctor appointments, late night arguments, and passwords sent in panic. You do not upload that to a cloud company to save two minutes of local setup.

02 / Connectivity

Works with the wifi completely off

Turn off your radio, sit on a delayed train, and run the entire scan. Ollama and TabPFN run in memory on your laptop without sending a single packet into the air.

03 / Ownership

You can swap the model whenever you want

No locked endpoints or changing terms. When a lighter model weight drops next month, change one line in the local script and keep your workflow intact.

Verification

Numbers and honest limits

84%
Extraction Accuracy
Measured across 50 hand-checked conversation samples.
Known failure mode

Where the parser still stumbles

On dry, sarcastic banter, Gemma regularly flagged jokes like "sure, I will buy you an island on Friday" as high-priority commitments. Sarcasm in multi-lingual chat groups remains an unsolved bug, so an explicit ignore list had to be added.