DEV Community

Jayana  Gunaweera
Jayana Gunaweera

Posted on

Hauntlog - A local ghost story generator👻

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

Hauntlog is a local ghost story generator. You paste a night of your smart home's sensor log, and Gemma tells the ghost story hiding in it: a hallway motion sensor firing while everyone sleeps, a tap that runs for four seconds, a study that drops to 14.5 °C, a front door lock that registers an unlock attempt with no keypad entry.

The haunting is in the log, so I made the log the only source of truth. Every scene has to quote a real log line, and the app shows each scene directly above the line that proves it. The sensors are the ghost in the machine, and the model is only allowed to describe what they actually recorded.

Demo

![Hauntlog home page]

![A story, with each scene above the log line that proves it]

Run hauntlog --demo to try it without a model. The demo includes one invented event (a basement piano) on purpose, so you can watch the app throw it out:

![The house lied: an invented event is dropped]

Code

GitHub logo JayanaGunaweera01 / haunt-log

👻A local ghost story generator.

Hauntlog

A local ghost story generator. Paste a night of your smart home's sensor log; Gemma 4 tells what happened while you slept, and every haunted moment has to point at a real log line.

Built for the Halloween "ghost story generator" prompt, on gemma4:e4b via Ollama. Nothing leaves your computer.

  1. Add a night: name the house, paste the sensor log (any text, one event per line, with times).
  2. Press Tell me what happened.
  3. Read the story. Each scene sits above the log line that proves it, a dread meter is computed from the log, and the log is shown with the cited lines marked.

Watch the demo on YouTube

Watch the demo: https://youtu.be/N7EwWpTVJPs

Screenshots

Add a night The story
Add a night The story, each scene above its log line
The house lied The log with cited lines marked
An invented event dropped Cited lines highlighted in the log

The rule it is built on: the model tells, plain Python decides

A smart-home log is dull. A model can make it terrifying, and can…

How I Built It

  • Model: gemma4:e4b through Ollama, using JSON-schema constrained decoding so every reply parses.
  • App: FastAPI and Jinja2 served on 127.0.0.1, with a readable JSON store in ~/.hauntlog. Nothing leaves the laptop.
  • Core idea: the model proposes, plain Python decides. I converted this from my earlier ScopeGuard project and kept its architecture:
    • A haunting must be in the log. The model quotes a line, and code finds that quote in the log (ignoring case, punctuation and line breaks). If it isn't there, the scene is dropped and listed under "The house lied".
    • Silence is not a haunting. A quiet night is told as a quiet night.
    • The model never writes a time or a number. Times come from the verified log line, and a scene or title containing a digit is replaced.
    • Dread is computed, not declared. The 0–5 dread meter comes from the verified lines (night hours, motion, opened doors, unknown sources), so a dramatic model can't inflate it.
  • Story shape: one prompt asks for a title, an opening, one scene per eerie log line in order, and a morning-after ending, so the result reads as one story and not a list of captions.

The cited lines are marked in the log, so you can see exactly what each scene rests on:

![The log with the cited lines marked]

Why Does Open Innovation Matter?

A smart-home log records when you are home, asleep and away. That is not something to paste into a hosted API. With an open-weight model running locally, the whole thing works offline, the only network call is to Ollama on localhost, and it costs nothing to re-run the same night for a different story. Because the constrained decoding and the verification live in my own code, a 4B-class model is trustworthy enough for the job.

Prize Categories

  • Best Use of Gemma. Gemma 4 E4B (gemma4:e4b) runs locally through Ollama and writes the ghost story: a title, an opening, one scene per eerie log line, and a morning-after ending. Its output is constrained to a JSON schema, and plain Python then checks every scene against the sensor log. Smaller variants such as E2B work too: set HAUNTLOG_MODEL to switch.

Top comments (2)

Collapse
 
abhisekroy169 profile image
Abhisek Roy •

Background music is really scary

Collapse
 
jayanagunaweera01 profile image
Jayana Gunaweera • • Edited

Hi, Abhisek! That background music was carefully chosen to set the perfect eerie vibe👻. Appreciate you checking out the ghost story generator!