Build Sembly AI

KINDAreplaces $17/mosaves $204/yrback to the verdict

0%0 of 17 items done

Saved on this device only. Tick prerequisites first, then work the phases in order · do not start one until the checks above it pass.

A local meeting notebook whose hard problems are capturing the far side of a call at all and proving you did, keeping two independently clocked audio tracks aligned over an hour, and producing tasks that never invent an owner or a deadline nobody said.

estimated effort multi-daythe files for this build are in the project pack

RuntimePython 3.12 with FastAPI and a plain HTML interface, running on the machine that recordsCaptureTwo independent tracks written to separate files as they arrive, never premixedTranscriptionA local speech model per track, segments stored with track, start and endAlignmentA shared wall-clock timeline with per-track drift correctionStorageSQLite beside the audio files, with search over segments

Before step 1

Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.

  1. installfree

    Why Runs the capture service and the interface.

    Get it python.org or your version manager. open ↗

    Verify python3 --version prints 3.12 or higher

  2. decidefree, or the price of a virtual audio device

    Why This is the whole product and it differs by operating system and version, so confirm it with a ten second test recording before writing anything else.

    Get it Read your platform's current documentation for capturing what the speakers are playing, grant the permission, and record ten seconds of music.

    Verify A test recording of the remote track contains audible sound, not silence

  3. have readyfree, plus disk for the weights

    Why These are recordings of other people talking, and sending them to a service is a decision that should be deliberate rather than a default.

    Get it Download a local speech recognition model suitable for your machine.

    Verify A one minute recording transcribes locally in an acceptable time

  4. installfree

    Why Imports the recordings other tools produce and converts anything you were sent.

    Get it Your package manager, or ffmpeg.org. open ↗

    Verify ffmpeg -version prints a version

  5. have readyfree

    Why Hours of two-track audio adds up faster than people expect and the notebook becomes a liability before it becomes a space problem.

    Get it Decide the retention period in days and check you have room for that many hours.

    Verify The configured retention and the available disk are both written in the README

Data model

Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.

- meetings(id, title, started_at, ended_at, consent_note, state) · the consent note is required before recording starts
- tracks(id, meeting_id, kind, file_path, started_at_wall, sample_rate, frames_written, rms_summary) · kind is microphone or remote
- segments(id, meeting_id, track_id, start_ms, end_ms, text, model_id, confidence) · times are on the shared timeline, not the track's own
- speakers(id, meeting_id, label, display_name, source) · source is track for your own voice, cluster for a guess, manual for a correction
- segment_speakers(segment_id, speaker_id, assigned_by) · assigned_by is diarisation or human
- items(id, meeting_id, kind, text, owner_speaker_id, due_text, segment_ids_json, state) · kind is decision, action or question, and owner may be null forever
- topics(id, meeting_id, label, segment_ids_json) · derived, rebuildable, never the only copy of anything
- Every generated sentence in this schema carries the segment identifiers it came from. There is no summary row without them.

Environment variables

These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.

VariableNeededExampleWhere the value comes from
DATA_DIRrequired./dataRecordings, transcripts and the database. Everything the notebook is.
MIC_DEVICErequiredBuilt-in MicrophoneChosen by name, because device indexes move between reboots.
REMOTE_DEVICErequiredSystem Audio CaptureThe call audio device. Getting this wrong records you twice.
SILENCE_ABORT_SECONDSrequired45How long a silent remote track is tolerated before the recording stops.
ALIGNMENT_TOLERANCE_MSrequired250The drift the alignment test is allowed at the end of an hour.
AUDIO_RETENTION_DAYSrequired60Recordings are deleted after this; transcripts and items are kept.
SPEECH_MODEL_PATHrequired./models/speechStored with every segment, because two models give two transcripts.

The build, in order

  1. Two tracks, or an honest refusal

    A recording captures microphone and call audio separately, and a silent far side stops the recording rather than being discovered later.

    1. Guessing which device is the call is how you get two microphones.

      Files capture.pydevices.py

    2. The start times are what lets you align the tracks later.

      Files capture.py

    3. This is the failure that ruins a notebook quietly.

      Files capture.pytests/test_silence.py

    done when · tick each as it passes
    watch out
    • Requesting system audio and getting a stream with no audio track, or a track of digital silence because a permission was refused without an error, produces a recording that looks complete and contains only you. Measure both tracks during capture, not afterwards, and make a silent remote track an error the user sees within the first minute rather than a discovery in the transcript.
  2. One timeline, two clocks

    Segments from both tracks line up at the end of an hour, not just at the start.

    1. The difference is invisible for a minute and fatal for an hour.

      Files timeline.pytests/test_drift.py

    2. Two sets of times in one table is how alignment bugs hide.

      Files transcribe.py

    3. The display is a view; the tracks are the record.

      Files views/transcript.html

    done when · tick each as it passes
    watch out
    • Assuming both devices produce exactly their nominal sample rate means a small constant error accumulates, and by the end of a sixty minute recording your reply sits several seconds before the question it answered, which makes the interleaved transcript read as nonsense and quietly ruins every note built on it. Measure frames against wall time per track, store the correction, and test alignment at the end of a long recording rather than the start.
  3. Your voice is known, everyone else is a guess

    Speaker labels distinguish what is certain from what was clustered, and corrections stick.

    1. It is the only speaker label in this build that is not a guess.

      Files speakers.py

    2. Show the user which labels are evidence and which are inference.

      Files diarise.pyviews/transcript.html

    3. The corrections are the most expensive data in the notebook.

      Files speakers.pytests/test_corrections.py

    done when · tick each as it passes
    watch out
    • Running diarisation across a premixed file, or across both tracks together, throws away the one piece of ground truth you actually have and then asks you to trust a guess about it, so your own sentences start being attributed to the client. Cluster the remote track only, and mark your own track by construction.
  4. Tasks that nobody invented

    Decisions, actions and questions each point at the seconds of audio they came from, and an unassigned action stays unassigned.

    1. An unresolvable citation means the item was invented.

      Files items.pytests/test_citations.py

    2. Filling the blank is the moment this product starts lying.

      Files items.pyviews/items.html

    3. 'Early next week' is information; a parsed Tuesday is a fabrication.

      Files items.py

    done when · tick each as it passes
    watch out
    • Asking a model for action items with owners produces a tidy table in which the quietest person in the meeting has been assigned three tasks they never accepted, and because the table looks authoritative nobody checks it against the recording. Require citations, resolve them, and make an unowned action a first class state rather than a gap to be filled.
what this build does not replace
after v1, if you want it

Need the files? The project pack on the verdict page hands your agent the whole brief · more meeting notes.