This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady

What I Built

I'm Israel, a student developer in Lagos, and in my learning pod (about ten of us, called "Flexbox") I hold the most dangerous title in any group chat: secretary.

When the call ends and everyone says "nice one, guys" and leaves, the secretary is the one still sitting there with a recording and a job: write the brief. Decisions, open questions, who's doing what by when. Before anyone forgets.

So I built Sloth Secretary, a small offline Python CLI that does the boring part for me:

sloth pod-call.m4a 

Give it an audio or video file from any call app and it writes:

  • a 2-line TL;DR (you can read it while your data is still loading)
  • decisions and open questions
  • action items grouped by person, with due dates when someone said one
  • a Markdown file plus a ready-to-paste WhatsApp/Telegram message

All of it runs on my laptop: open Whisper weights for the listening, Gemma for the writing. There's no API key, nothing gets uploaded, and nobody sends me a bill.

And for the truly lazy:

sloth --watch ~/Recordings/pod-calls 

Drop a recording into the folder, go and do something else, and the minutes turn up next to it. Hang around, save energy, get there eventually. Very sloth.

Demo

My real pod's call stays private (more on that below), so I wrote a fictional 4-minute standup: Chiamaka, Tunde, Ngozi and Emeka of "Pod Baobab" building DanfoFare, an app for crowdsourcing Lagos bus fares. I turned the script into audio offline with Piper TTS, one open voice per person, and ran the real pipeline on it.

Terminal run of Sloth Secretary

And here are the minutes it wrote, rendered:

Generated minutes

(There's a 13-second animated version, assets/demo.gif / demo.mp4, in the repo.)

These are the real, untouched outputs, so here's an honest grade. Gemma 3 4B caught all 8 tasks and gave each one the right owner. It also put the projector room on Wednesday (it's Thursday), dropped the Sunday deadline on Emeka's Supabase task, and missed one decision ("no real phone numbers in the demo") and one open question ("who presents?"). That's why Sloth Secretary never sends anything by itself: it prints a preview, --edit opens the draft in your editor, and sloth x.minutes.json re-renders after your fix. The sloth writes the draft; you spend thirty seconds checking it.

Code

https://huggingface.co/Ajewoleisrael2/sloth-secretary

How I Built It

Five plain steps, all open source:

  1. ffmpeg turns whatever the call app exported (.m4a, .mp4, .ogg, WhatsApp voice notes) into 16 kHz mono WAV.
  2. faster-whisper (open Whisper weights, small, CPU, int8) transcribes it with timestamps. Voice-activity detection skips the long "can you hear me? …you're on mute" stretches.
  3. Gemma via Ollama reads the transcript and returns JSON that has to match a schema (structured outputs), so even a small model can't wander off into an essay. --model swaps in any Ollama model, and --backend llamacpp --gguf model.gguf runs a GGUF through llama-cpp-python with no Ollama at all. I tested both with Gemma.
  4. Map-reduce for long calls. Small models forget the middle of a 50-minute transcript, so it's cut into ~10-minute chunks (with two lines of overlap, so "Tunde, can you…?" never loses its "Yes, by Wednesday"). Each chunk becomes notes, and the notes get merged.
  5. A validator that doesn't trust the model. It dedupes items, folds the TL;DR down to two lines, and adds a "⚠️ Please double-check" section when something looks off: a "decision" that overlaps an open question, a task owned by "Me", or a name that never appears in the transcript.

That validator exists because of my first run. Whisper had never met Ngozi (and my American and British demo voices didn't help), so it wrote "Gozi". Emeka became "Imeka", and Supabase became "Superbase". Then Gemma, being helpful, listed "use 30 days of data" as a decision, when the group had literally said "let's not decide now." So I added --names (or a lazy sloth-names.txt in the watch folder). The names go into Whisper's initial prompt and hotwords, and the validator snaps misheard names onto the real ones. On the second run every name was right and the fake decision was gone. Both runs are in examples/.

The sloth earned its name the hard way, too. My first full hour-long run on an 8 GB test machine ran out of RAM, and Gemma 4B got OOM-killed on chunk 3 of 6. Now Whisper runs in a child process and hands its memory back before Gemma loads, a crashed model runner gets one patient retry, and every finished chunk is cached. If NEPA interrupts a run, the same command picks up where it stopped. Slow and steady, but it finishes.

It's under 1,000 lines of Python with one required dependency (faster-whisper). Ollama gets plain urllib, and watch mode just polls, waiting until a file stops growing so it never grabs a recording that's still copying off your phone.

Why Does Open Innovation Matter?

My teammates' voices aren't mine to upload. People say things on a pod call they'd never post: "I travelled for a wedding," "I haven't started," "my laptop is dying." A secretary should protect that. Here the audio, transcript and minutes never leave the laptop. Once the models are downloaded, it runs with the Wi-Fi off.

Data costs real money in Lagos. Uploading an hour of audio burns data before a cloud API even sends its bill. Here the models download once, and every call after that costs nothing.

NEPA doesn't check your sprint schedule. When the power or the router goes, a cloud tool stops working. This one keeps going on a laptop battery.

Zero API bill. A student budget has no line for "transcription subscription."

I can swap the brain. When a better open model comes out, I change one flag. Nobody can deprecate my secretary.

The tradeoff is real. A 4B model on a CPU is slower and vaguer than a giant cloud model, and Gemma 3 1B was faster still but wrote things like "Update on the fare chart (by Ongoing)". For me, local, private and free wins, as long as a human gets the last look. That's why the preview step is part of the design.

The Lazy Payoff

On 16 October 2026 my pod had a ~53-minute ideation call, and I was secretary. When it ended, I had nearly an hour of audio to go back through, pulling out the ideas, decisions and who-does-what, and a brief to write before everyone forgot. My first local transcription with Whisper base came out patchy. Still, it showed me the hard part could run on my own machine, and that night this project started.

Real numbers, measured in a CPU-only sandbox (2 ARM vCPUs, 8 GB RAM, no GPU):

Run Audio Transcribe (Whisper small) Gemma Total
Demo standup, single pass 3 min 56 s 41.3 s 77.3 s (gemma3:4b) 1 min 59 s
Same transcript, forced map-reduce (3 chunks) 3 min 56 s (reused) 247 s (gemma3:4b) 4 min 7 s
The real pod call (63-min file, talking ends ~53 min; timings only, minutes deleted) 63 min 10 s 310 s 1,004 s (gemma3:4b, 11 chunks, low-RAM flags, 1 crash auto-retried) 21 min 56 s

Whisper finished the hour in about 5 minutes, because VAD skips the "you're on mute" silences. Gemma spent about 17 minutes reading eleven chunks and merging them. It crashed once along the way, and the retry carried on without me. The whole call came back as a draft in 22 minutes with nobody watching, on two CPU cores.

That's how the secretary job went from an evening chore to a coffee break. I start it, make tea, come back to a draft, give it a proper skim, fix what's wrong, and paste it into the group chat.

I'll take that trade every week. The sloth gets the hour, and I keep my evening.

Prize Categories

Best Use of Gemma: Gemma 3 is the writing brain. I ran gemma3:4b (the default) and gemma3:1b locally through Ollama, and gemma-3-1b-it as a Q4_K_M GGUF through llama-cpp-python, all on CPU and all offline.