Back to work

Built solo · 2026 · In daily use

AI Application

V

A voice that runs my AI sessions like a small company, and asks first.

V lives on my Mac. Call her or type to her and she carries my requests to my Claude Code sessions. She also runs a multi-AI system that works like a small company: every job a ticket, every delivery checked against evidence, nothing sent without my yes.

RoleProduct · Voice pipeline · Agent orchestration · Safety

≤ 15 s
from a session finishing to V reporting it; it used to take up to nine minutes
~30 s
to relay a finished brief to the next session, a handover that waited on me before
0 / 22
strangers let through by the voiceprint, real-voice test
1,700+
automated tests passing, every one silent

The General Manager

Every job, a ticket.

Anything with real output becomes a ticket. I approve it once; a project manager writes the brief, and she hands it to the right session and relays the result in about thirty seconds.

The Hard Gate

Nothing ships without a yes.

Push, deploy, spend, send: each waits for one spoken confirmation, judged against my own words by a separate model. The brain has no way around it.

One Voice Holds the Keys

One voice can say yes.

Guests get a brain of their own, with no mail, files or terminals. Permission follows the voiceprint, not the words: “Michael said it’s fine” opens nothing.

Checking, Not Trusting

Sent is not started.

A delivery manifest counts as done; saying “done” does not. She reads the session’s own transcript for her instruction, counts only its actions, and looks before she reports.

Tech Specs

Brain
Claude Opus 5.5 in one resident Claude Code process · helpers started per call: sealed guest brain, Sonnet interrupt judge, Haiku send judge, Haiku sent-claim check
Workflow
tickets, written briefs and delivery manifests through a command-line tool · one approval per ticket · handovers relayed automatically, about 30 s
Roles
Claude for code, copy and coordination · OpenAI for images · each role with its own written charter
Panel
menu-bar panel in native AppKit · type, call, hang up · mic off closes the input stream
Listening
sherpa-onnx wake word · Silero VAD · Qwen3-ASR 0.6B on MLX, loaded for calls · SenseVoice for talk-over
Speaking
Qwen3-TTS 1.7B, loaded for calls, streamed sentence by sentence · her voice is customizable and can be cloned into a different one
Identity
CAM++ voiceprint, nearest-neighbor scoring, ~11 ms a sentence · speakers split when two talk in one breath
Turn-taking
Smart Turn v3.2 · trailing-word rule · WebRTC echo cancellation · output follows AirPods
Desk
Ghostty via AppleScript · Claude Code Stop and Notification hooks · full shell
Memory
core · topics · archive, tidied weekly with undo · skill book · daily backups
Mail
Gmail, read-only by design
Runs on
M5 MacBook Pro, 16 GB · about 1 GB between calls, 5.3 GB on a call · speech and identity local, only the Claude processes online
The full storyRead the full storyCollapse

Why a voice

I keep several Claude Code sessions running at once, each on its own project. Their news used to arrive as windows I had to go and read. V sits between us: sessions report to her when they finish, she tells me what happened in a sentence or two, then asks whether I want the rest. I answer in plain speech, in English or Chinese, or type in her menu-bar panel when speaking is not convenient: one brain, one conversation. She turns what I say into instructions written for the session that needs them, and keeps a ledger of everything she has sent.

Run like a small company

The sessions now work inside a multi-AI system that runs like a small company, with written rules. I am the boss and V is the general manager; each project has a project manager, and roles with their own charters do the work. Models from two vendors share it: Claude handles code, copy and coordination; OpenAI handles images. Anything with real output becomes a ticket. I approve it once, the project manager writes the brief, and V hands it to the right session. Work comes back with a manifest: files, checks run, evidence, what is unfinished. V checks the evidence before I see it, then I accept or send it back. Each closed ticket ends with three lines: what went right, what went wrong, what changes next time. An audit role looks only at how the system runs, not at what it makes, and repairs its tools. The rules live outside her code, so the job could go to someone else.

Checking, not trusting

Once, a dispatch reported as sent had landed in a bare shell where Claude Code never started. So every dispatch is checked against the session’s own transcript, and progress is counted only from the session’s replies, tool results and commits; a delivery manifest counts as handed in, a spoken “done” does not. Handovers that used to wait on me now relay themselves: a finished brief reaches the next session in about thirty seconds, a delivery manifest reaches review in twenty, and a session that stops is reported within fifteen seconds instead of minutes. When something stalls, she looks before she reports.

Talking like a person

A wake word or the call button opens the conversation; 45 quiet seconds send her back to standby, and ten minutes in standby end the call. A turn-taking model and a rule about trailing words keep her from answering half a sentence. Talking over her was the hard part: on a laptop speaker, her own echo and a real interruption look the same to a voiceprint, to loudness and to echo cancellation. What tells them apart is content. So she ducks to forty percent, pauses to listen, and a fast judge decides from the words: stop, carry on, or let a side conversation pass. If her first sentence is not ready after two seconds, she says “let me think” rather than go silent.

Who gets to say yes

Anyone in the room can talk to her. Anyone who is not me is answered by a separate guest brain that has no mail, no files, no terminals and no sessions; the limits are hard, not a request. Sending, granting and stopping her mid-task follow my voiceprint alone. Anything that leaves the machine — a push, a deploy, a purchase, a message — is read back in a sentence and goes out only when a separate model judges my answer a yes; for a ticket I have approved, that yes was given at the start. Another check stops her from saying something was sent when it was not. A grant has to come from my voice within the last two minutes, and it lasts one conversation. When two people speak in one breath, the sentence is split by speaker before any of it counts as mine.

Around the day

On the first start of the day she reads new mail, files what needs doing as to-dos, and offers a brief: the short version first, details on request. To-dos repeat, split into steps and nudge me when due, at most once every three hours. Say the meeting has started and she goes quiet and writes down every line, who said it, until asked for a summary. A skill book holds what she has learned about how I work; new entries are on trial until they have worked three times. She can also open Blender and model by voice through a locked-down bridge.

Engineering notes

Python, with 1,700+ passing tests that never make a sound. Between calls only the brain, the wake word and a small fallback recognizer stay loaded, about 1 GB; a call loads speech recognition, synthesis and the helper Claude processes, about 5.3 GB, and hanging up unloads them. Typing and voice share one brain behind a lock, so two copies can never hold the same conversation. Speaker ID and the quick interrupt recognizer run on the CPU. Every benchmark is offline and silent, because anything played through the speaker would be heard as me. Memory comes in three layers: a short core she always carries, topics she looks up, and an archive that is never deleted. Still rough: the wake word misfires, standby memory sits at 0.9 GB against a 0.6 GB target, and the written rules are a draft I am following before I have finished them.