Vibe Coding Open Core Out of its Lockbox III: The Source Awakens A developer forking the open-core Meetily product with AI coding tools reports that implementing speaker diarization requires a full pipeline redesign, as the legacy code for the feature is not wired into the active transcription system. The effort, rated as very high in the project roadmap, involves adding embedding models, clustering algorithms, storage, and UI components, testing the limits of AI-assisted development. This is the third article in a series about forking an open-core product with AI coding tools. Part 1 laid out the roadmap of what was gated behind the Pro paywall. Part 2 executed the fork: rebrand, telemetry strip, first feature. It proved the easy stuff was as easy as it looked. Part 3 is about the stuff that isn’t easy. Speaker diarization identifying who said what in a meeting is the one feature where the open source codebase and the Pro version are on even footing. The Meetily website marks it as “Coming Soon” for every tier, including Pro. Neither side has shipped it. The roadmap from Part 1 rated this as Very High effort. The legacy code existed but wasn’t wired into the active pipeline. The architecture to support it touches the audio pipeline, the database schema, and the UI. Let’s find out if that estimate was right. What the Codebase Actually Has what-the-codebase-actually-has The Meetily codebase has a file called audio/stt.rs that contains speaker embedding extraction using PyAnnote models. It has EmbeddingExtractor , EmbeddingManager , and SpeechSegment types. It’s real code that was inherited from a screenpipe fork. But it’s not wired into anything. The active transcription pipeline runs through whisper engine/ and parakeet engine/ . Neither has any concept of speakers. The TranscriptResult struct that carries transcription events to the frontend has fields for text, timestamps, confidence scores, and language. No speaker ID. I poked deeper expecting the pyannote module to have been stripped from the repo. That kind of legacy code usually gets deleted when the pipeline is rewritten. But it’s still there. The pyannote/ directory has real Rust bindings for speaker embedding extraction and segmentation models. It’s not a stub. It’s code that was written to do exactly what diarization needs, connected to a pipeline that no longer exists. So the legacy code is not a shortcut. It’s evidence that someone thought about this problem before, but the implementation that shipped is a single-user transcription engine with no speaker awareness. Building diarization means adding a new dimension to every layer of the pipeline. The Architecture Problem the-architecture-problem Diarization requires four things that don’t exist in the codebase: An embedding model that can produce speaker fingerprints from audio segments A clustering algorithm to group those fingerprints into distinct speakers A storage layer to associate each transcript chunk with a speaker ID A UI to display speaker labels and let users name the speakers The embedding extraction needs to happen in real time, alongside transcription. That means the audio pipeline which currently runs a single pass through Whisper or Parakeet now needs to produce both text and speaker embeddings from the same audio buffer. This is where the “vibe coding” thesis gets stress-tested. The PDF export spec from Part 1 had clear boundaries and no external dependencies. The template editor spec from Part 2 had a complete Rust backend waiting for a frontend. A droid agent could handle both because the problem was well-defined and the infrastructure was already in place. Speaker diarization is different. It’s not a bolt-on feature. It’s a pipeline redesign. The Research the-research Before writing off the problem, I did what any reasonable engineer would do: looked for someone who already solved it. There’s a project called WhisperX https://github.com/m-bain/whisperX with 22,000 GitHub stars. It does exactly what we need: batched Whisper transcription with word-level timestamps and speaker diarization, powered by pyannote-audio. The pipeline is: - Voice activity detection Silero or pyannote to strip silence - Whisper ASR for transcription - Forced alignment with wav2vec2 for word-level timestamps - Speaker diarization with pyannote-audio to cluster speakers - Assignment: map each word’s timestamp to a speaker turn The whole thing runs at 70x realtime on a GPU and is BSD-2-Clause licensed. The diarization model it uses, speaker-diarization-community-1 , is CC-BY-4.0 from pyannoteAI. Both licenses are compatible with the MIT fork. Pyannote-audio is already partially present in the Meetily codebase. The pyannote/ directory has real Rust bindings for embedding extraction and segmentation. Someone already started this work. They just didn’t finish wiring it into the active pipeline. The fork’s approach wouldn’t be to build speaker diarization from scratch in Rust. It would be to integrate WhisperX as a sidecar. The same architectural pattern the codebase already uses for local AI inference via the llama-helper binary. Transcribe in real time with the existing Rust pipeline. When the meeting ends, or during a pause, hand the audio to a WhisperX sidecar process that runs diarization and assigns speaker labels to the transcript chunks. This is still a significant engineering effort. The sidecar needs to be packaged, the results need to merge back into the existing data model, the TranscriptResult struct needs a speaker id field, and the frontend needs to display speaker labels. But it’s not a moonshot. It’s a known problem with a known solution and a proven open source toolchain. Here’s the spec I wrote for it: SDD: Speaker Diarization via WhisperX Sidecar Goal Add speaker diarization to LibreMeet — identifying who said what in a meeting. Uses WhisperX BSD-2-Clause as a Python sidecar process, following the same architectural pattern as the existing llama-helper sidecar for local AI. Architecture The existing transcription pipeline stays unchanged for real-time capture. After a meeting is recorded, the user can run diarization as a post-processing step. The flow: 1. User clicks "Identify Speakers" on the meeting details page 2. Backend exports the meeting's audio file to a temp location 3. Backend spawns a WhisperX Python sidecar process 4. WhisperX runs: VAD → forced alignment → pyannote diarization → speaker assignment 5. Sidecar writes results as JSON: array of {speaker id, start sec, end sec, text} 6. Backend reads the JSON, assigns speaker IDs to existing transcript chunks 7. Frontend re-renders with speaker labels Requirements Sidecar Script - Path: libremeet-sidecars/whisperx diarize.py - Python script using whisperx pip package - Accepts: --audio