DEV Community

Gagan Kadam
Gagan Kadam

Posted on

Group Project Ghost: I was too lazy to be my team's nag, so I built one

Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Submission πŸ¦₯

Every group project has one person who becomes the de-facto nag. The one who chases the teammate who hasn't started, reminds the one who missed the deadline, and slowly turns into the group's unpaid project manager.

I am that person. So for Hacktoberfest Week 3 β€” Slow and Steady, the sloth-themed one β€” I built the opposite of that person: Group Project Ghost, an agent too lazy to nag, which is exactly why it works.

What it is

One command reads your group's shared task list, asks a local open-weight model (gemma3:4b via Ollama) to write the follow-ups you'd otherwise compose yourself, and hands you one ready-to-paste message per teammate β€” plus a spoken two-line morning brief you can listen to without sitting up.

$ uv run ghost.py
2 overdue β€” nudges ready to paste:

--- to arun ---
Hey Arun, just checking in on the frontend for the library project β€” the
issue/return pages were due last week. Let me know if there's anything I
can do to help get them sorted out...

--- to priya ---
Hey Priya, just wanted to gently nudge you about the report for the DBMS
project β€” it's been a little while since it was due on the 21st! ...
Enter fullscreen mode Exit fullscreen mode

And the sloth mode of the whole thing:

$ uv run ghost.py --brief --speak
Morning, team. Arun's still tackling those return pages – due Oct 20.
Priya, focus on getting that 6-page report done by the 21st.

saved brief.mp3 β€” play it and stay in bed.
Enter fullscreen mode Exit fullscreen mode

The model writes the words (locally β€” the task list never leaves my laptop), and ElevenLabs' text-to-speech reads the brief out loud in about ten seconds of George's voice. I lie in bed, I'm informed, I do nothing.

Demo: the terminal output above is verbatim β€” and yes, the whole point is that you listen to your team's status instead of reading it.

How it works

Your project is a boring YAML file β€” which is the point:

project: DBMS Mini Project β€” Library Management
tasks:
  - task: Write the 6-page report
    owner: priya
    due: 2026-10-21
    status: todo      # done / wip / todo
Enter fullscreen mode Exit fullscreen mode

The whole loop in ghost.py:

  1. Load the tasks, compute what's overdue (nothing clever β€” a date comparison).
  2. One prompt per slacker, with a tone flag (--tone polite | sloth | passive-aggressive).
  3. Ollama does the composing at http://localhost:11434 β€” standard /api/chat, no cloud.
  4. --brief --speak renders the two-line brief through the ElevenLabs Python SDK.

There's an offline --selftest that checks the overdue logic without touching any model. It immediately earned its keep: on day one it caught that my demo data had nothing actually overdue on the test date β€” a broken fixture, not broken logic. Fix the data, keep the assertion.

The lazy payoff (the bonus question)

Honest tally, and I'm labeling it as an estimate because this shipped this week: composing nag messages and mentally tracking "who owes what" runs me about 10 minutes and a chunk of attention per day on a group project. Now it's uv run ghost.py, skim, paste β€” about 20 seconds β€” and the morning brief means I often don't even open the task file. I'll update these numbers if a longer run proves me wrong.

The real saving isn't the minutes. It's never having to be the nag again. The message exists before I emotionally invest in sending it.

Why open innovation matters here

  • My teammates' data stays mine. The task list, who's behind, and what they're working on never leave my machine β€” the local model sees it, nobody's server does. The only text that ever reaches an external API is the two-line brief I chose to speak.
  • It runs on the laptop I already have. gemma3:4b is 3.3 GB. No API bill, no seat counts, no "free tier" that expires mid-project.
  • The model is a dial, not a contract. Ollama serves whatever I want β€” today a 4B model that fits the tone task, tomorrow something bigger if nudges start sounding like a robot. An open model I can swap beats a closed one I can only complain about.
  • Offline core, voice edge. Everything except the optional spoken render works with the network unplugged.

What I deliberately didn't build

No WhatsApp/Discord/email sending. Integration eats the whole budget of a three-day build and turns a lazy tool into infrastructure. The ghost prepares; one paste is the send β€” and pasting isn't the tedious part, composing is.

What shaped it

I checked what everyone else was building before picking a lane β€” the Week 3 board was filling with file tidiers and commit bots:

Nothing was voice-first yet, and "status you listen to from bed" felt like the slothiest possible version of the prompt.


Code: github.com/grkadam7/group-project-ghost.

Entry for the Hacktoberfest Open-Source AI Challenge: Week 3 (Slow and Steady) β€” built with a local gemma3:4b via Ollama, voice via ElevenLabs. The teammates in the demo data are renamed; the dread is real.

Top comments (0)