Newest first. The app shows these too, up to the version you have; this is the whole run.
Newest first. The top section is the release being cut, and it is the only place its notes are written: release.sh reads it for the GitHub release body and for the "what's new" pane Sparkle shows before an update, and refuses to publish when its version disagrees with VERSION.
A section starts at a heading that is ## followed by a version number, so headings inside an entry can be anything that is not one of those.
Listen has a website of its own at listenbrain.app, and everything the app used to send you to GitHub for is there instead: the release notes, the telemetry dictionary, the managed-deployment guide and where to write when something is wrong. Updates come from there now too.
Sparkle used to fetch its feed and the download from the GitHub repository. Both now come from dl.listenbrain.app, and the app declares that host in the InternetAccessPolicy.plist a firewall like Little Snitch reads, so the change is visible where it should be rather than a surprise in a connection log.
Copies before this one keep updating from GitHub and always will. The feed address is compiled into a build and cannot be changed afterwards, so releases are published to both places, and will be for as long as anybody is still running an older copy.
Nothing about what is sent has changed. The check is still a request for a file listing versions, it still carries nothing about you, and turning it off is still one setting.
Help, Listen Website now opens listenbrain.app. Release Notes opens listenbrain.app/changelog, which has every version rather than stopping at the one you have. The Privacy pane's "see exactly what is shared" opens listenbrain.app/telemetry. Reporting something opens listenbrain.app/support, which says what to send and, more usefully, what not to: never a recording or a transcript.
On the iPhone the same four moved, and the sentence that travels with Share Listen was rewritten. It had been describing a Mac recorder that writes down who spoke, which is what Listen was two positionings ago.
Showing Listen to somebody meant showing them your colleagues. Settings, Appearance now decides how much of a person's name the screen says: the whole name, the last initial, or the first name alone. Nothing on disk changes either way. Alongside it, a person's card is easier to look at and to edit, and a copy holding a downloaded update can finally tell you a newer one exists.
A demonstration puts a real library on somebody else's screen: a roster of colleagues' full names, the addresses beside them, and a transcript with both. Appearance is a new section under General with one choice in three.
Anything but the full name masks the addresses on a person's page as well, as d*****@acme.com with the domain kept, because a shortened name sitting over a whole address hides nothing. The mask is a fixed five characters whatever the address is: how long somebody's address is narrows down what it says.
The last initial is kept rather than dropped, and that is the choice worth explaining. Surnames get typed in the first place to tell two people called Daniel apart, and dropping the surname puts them back together on exactly the screens being demonstrated. One letter is not what identifies somebody to a room.
It changes what is drawn and nothing else. The transcripts, your notes, the generated profiles and the people directory keep the whole name. The CLI prints it, an agent over MCP is answered with it, an exported transcript carries it, and the search index is built from it. Renaming somebody shows you the name you are editing, and so does clicking a recording's title to rename it. The setting is stored on this Mac only and is not synced, which is the point: the laptop on a projector is not in the same room as the one on your desk, and your phone has its own.
Recording titles follow. A title Listen derived from who spoke is re-derived with the names written the chosen way, so "Call with Daniel Vermeer" reads "Call with Daniel V." A title you typed yourself is left alone, because there is nothing in a sentence that says which words are a surname and guessing at one is worse than leaving it.
Known limitation: clicking a speaker to see only their recordings puts their whole name in the search field, because that text is the search. It is the one place the setting does not reach.
Details (1142) reads Details (1,142).Reported from a Mac left running: an alert offering 0.43.0, an Updates pane saying it was downloaded and ready, a greyed Check Now, and nothing anywhere in the app to say that 0.44.0 had shipped ten minutes earlier. Both sentences were true. Once Sparkle is holding a staged update it stops fetching the appcast, so a copy in that state cannot learn about the next version by any route it offers.
Listen reads the release feed itself now, one request to the same URL. The pane and the alert name the newer version when there is one, and Check Now is never greyed. Installing what is already downloaded is still the only move; it is now stated as the way to get to the newer one rather than left looking like a stale offer.
Opening People & Memory used to pin a core for over a minute; it's a few seconds now. Every sheet, field and button in the app draws on Listen's own dark ground instead of the system's grey, and there is one blue instead of three. A handful of correctness fixes too: who a stopped call re-arms on, whose selection a detected meeting is allowed to touch, and which of a person's links are real.
Opening the pane pinned the main thread at 100% for over a minute and never settled. Four separate costs stacked on every claim on every receipt: an alias comparison redone per card, a policy JSON-decoded per call, a per-person roster walk that read every receipt in the library forty times over, and a contacts file decoded on every dependency check. Measured against a copy of the real library (95 recordings, 40 people, 418 processed parts): 100% CPU for about 100 seconds becomes idle within 10. The roster draws as a table now instead of one stack row per person, so it no longer grows the pane by 24 points a head and the controls under the list stay reachable.
Sheets, single-line fields and plain buttons across the app get one definition each, replacing years of things that looked close to right: the dictionary's word list and the Developers pane's dump sit on Listen's own well instead of a grey system scroll view, eighteen input fields across fourteen files draw the app's own bezel instead of the system's near-black, and the Ask setup wizard, the merge sheet and six more surfaces stop painting the system's material over the navy canvas underneath them. A compiled accent-color asset replaces three different blues in use at once (a toggle's #4079FA, a selected row's #2B56CC, a button's #5C7CFF) with one, checked at build time so the two copies of that color can't disagree again.
Seven buttons on the dictionary pane collapse into one Add button and a menu, the way the person page already handles its rarer actions.
A person's card is something you can correct now. A detail that is true but no longer current can be retired without deleting it, a promise filed under the wrong Daniel can be moved to the right one, and a word the transcript misheard can be fixed everywhere it appears rather than only where you noticed it. Writing a note by voice uses the same recorder the chord does, which removed a second one.
"Daniel works at Hotspotty" names a company he co-founded and still owns, and is no longer what he does. The sentence is true, the quote under it is right, and it should not be the first thing the card says. Hide throws away something true and Correct Detail rewrites words that were never wrong, so the page had no honest move for it.
Outdated is the fourth reader verb. It sets the claim's status to historical rather than inventing a fourth status, because every list in both apps, the CLI and the MCP packet filter on ["historical", "retracted"], and a new string would have to be taught to each of them; whichever were missed would keep a retired claim on the front page. A separate flag records that a reader decided it rather than the extractor, which may only retire a claim on direct asserted evidence carrying a stated effective date. The page prints "Outdated" against one and "Historical" against the other, so the two provenances are never read as one.
The label itself does not change. A detail can be reworded and it can be moved to somebody else, but "Works at" cannot be edited into "Co-founded": the predicate is the extractor's vocabulary rather than a word for a reader, and "co-founded" is not in it. In the case that prompted this the label was not wrong, it was stale, which is what Outdated says.
listen context outdated|current <claim-id> is the same move from a terminal.
Two people share a first name, Listen keeps one card for the name, and the other Daniel's promise sat under your Daniel with nothing to do about it but open the recording or press Delete, which throws away a sentence that is true. Reassign and Correct Wording are on commitments and on details now. The claim keeps its quote, its recording, its tick and its corrections, and a name nobody has yet is added to the roster on the spot, with no recording and no provider involved. listen context reassign <claim-id> <name> is the same move from a terminal.
A ticked commitment stays put for the rest of the visit and is behind "Show completed" on the next one, so a year of working with somebody is not a column of struck-through lines. The tick lands immediately: it used to wait about a second on iPhone for the corrections file and the lock a sync pass holds on it, because the write preceded the check rather than following it. Delete has always been a hide, and says so with an Undo under both lists.
Correcting a detail offers to fix the word behind it only when the edit looks like a mishearing rather than a change of mind. Measured against the case that prompted this: "HealthBody" for "Hotspotty" codes to h4313 against h3213 and is 7 edits apart where the allowance is 3, so no offer came, nothing said why, the transcript kept the wrong word, and the next extraction would have produced the same wrong detail. The two pairs the guard was built on still pass, "Vispa" to "Visma" at distance 1 and "Oxceed" to "Oxide" on one key.
The guard is unchanged for the automatic offer, which is Listen speaking unprompted and should stay conservative. "Fix This Word Everywhere…" on any corrected detail runs the same tokenising with that one judgement skipped, because the reader was in the room and asking is not being told. Every other check still applies, including the refusal to make a rule whose replacement is an ordinary English word.
Every row led with its date and kept Commitment in the label's tooltip, which is where you put something you have decided nobody needs to read. The kind is why a line is on the card; the group heading does not recover it, because "What Daniel wants" holds goals, preferences and interests together; and the date answers a question nobody asks until they are already reading that line. The kind is the heading now, and the date fades in under the pointer, with the words in the row's accessibility label because a reader with no pointer never meets them. A card can also be read one kind at a time.
The note sheet had a Record Voice Note button, a level meter, its own recorder and engine behind about forty lines of Task juggling, and it handed the words over in one lump at the end. It calls the same pipeline the chord uses now, HUD, model handling and permissions included, and the button, the meter, the recorder, the engine, the 120 second deadline and the AVFoundation import are gone.
The microphone sits on its own strip inside the well rather than floating over the text. Ask can float its one because a question is one line that never reaches the corner; a note is paragraphs, and the sixth of them would run underneath.
Two fixes measured alongside it. The well is a fixed height rather than a minimum: the window does not resize, so a well with a minimum took every point nothing else claimed, and pressing the microphone swapped two lines of status for one and grew the box under the writer's hands. And a dictation that comes back with nothing, silence or a cancel, puts the resting line back, where the sheet used to sit saying "Transcribing on this Mac…" for ever.
The sheets were driven through tools/axprobe against a demo library rather than a real one: the text area measures 510 by 208 idle, listening and after the words land, and a dictation of a quiet room leaves the sheet where it started. 146 context checks, 30 review-card checks and 12 reassignment checks pass, and 6 new assertions cover the retirement, its round trip, and that it writes no stamp key an older Listen would refuse the whole corrections file over.
This Week became a period you can name, and pressing a day replays it. Alongside that, the app stopped spending a core on a library where nothing had changed, and a person's page that used to never finish loading now answers in under two seconds.
"Last 7 days" ending on a Tuesday afternoon is nobody's week. Its first and last bars were part days, its week bars started on whichever weekday you opened the app, and two readings an hour apart were two different reviews, so nothing could be compared with the week before it.
The window is now a named period: this week, last week, this month, last month, this year. Weeks run Monday to Sunday whatever the locale's first weekday is, and a finished period ends at its own last second rather than at this moment. On a Monday morning "this week" is one day of library and seven days of week, so the timeline draws seven bars with six still to come, and a day that has not happened yet draws its baseline and nothing else, because empty and not yet arrived are different answers.
Pressing a day replays it. The interval's stars arrive in the order they happened, spaced by the real gaps between them, rather than being filtered down to it. A review is still derived rather than stored, so nothing is generated on a schedule: the home row becomes the finished week until it has been opened, and the Review menu opens whatever is waiting.
A detail you press opens beside the picture rather than replacing the deck, long cards page eight details at a time and remember the page you left, and the last card is now the workspace the walk was building towards, with every conversation and note in the window listed and lit at once. The composer under the galaxy takes the review as its subject, so a question about it carries the window's own dates.
Pressing a lit row again puts its card away, which is what the cross on the far corner of the window did and nothing else said the row could do.
A card reading "Thinks Oxide is better than Vispa" is not a detail the model got wrong. It is two product names the microphone got wrong inside a sentence that is otherwise what was said, and Correct Detail wrote one row against one claim: the transcript kept the wrong spelling and the next recording produced the same wrong detail to correct again.
When a correction is a word swap, Listen now offers to fix the word itself, with the count and the before and after lines on one sheet. Saying yes adds the dictionary entry and runs the backfill, so the transcript, search and next Tuesday's meeting all get it. Four guards stand in front of that, because a wrong yes rewrites the library: it has to be a word swap rather than a change of mind, the pair has to sound alike, the replacement must not be a word the language already has, and a pair already done or already refused is never offered twice.
A backfill used to take the memory with it. A claim is only as good as the file that proves it, so rewriting a transcript dropped every receipt whose stamps had moved and the claims went with them: measured on the real library, two rules firing on seven sentences in five recordings emptied five people's cards, one of them while it was on screen in front of the person who had just corrected it. Re-reading four of them by hand cost 18 requests and did not give the same claims back, because an extraction is not a pure function of its transcript.
A dictionary backfill is the one file change this app can describe exactly, a known word becoming another known word by a rule somebody read first, so the claims are now replayed rather than re-derived: quotes and wording are rewritten by the same rules, receipts are restamped, and every id downstream of the words is recomputed so corrections and reconciliations follow. Nothing is queued and no model is asked. The proof rule survives it: a replayed claim whose new quote is not in the new file is left alone and the old path takes over. Generated summaries are rewritten too, because they are the model's prose; your notes, chats and saved answers are not.
Every line of a person's card led with the date it was said and kept the useful half, what kind of detail it is, in a tooltip. The kind is why a line is on the card at all, and the heading above the group does not recover it: "What Daniel wants" holds goals, preferences and interests together. So the kind is the heading now and the date appears at the end of the line when the pointer is over it, the way an answer shows its timestamp in Ask.
Above the details there is a row of filters, one per kind the card holds, most common first. Tap Commitment to see the eleven commitments in a card of forty-six, tap Blocker as well to see both, tap All to come back. The count follows: "Details (11 of 46)". iPhone has the same row, and both apps now show the same qualifiers under a line, so "Planned" and "Reported" mean the same thing wherever you read them.
The box you type a note into was the system's own grey rectangle with a square edge, inside a window that is Listen's blue-black: two panes bolted together, around the one thing on that sheet you actually use. It is a proper well now, the same lift the library's rows have, with a rounded edge that takes the app's colour while the caret is in it, room around the words, and a line saying what the note is for instead of an empty void.
The microphone moved into it, too. Recording a voice note was a button called Record Voice Note with a level meter beside it, running a recorder of its own and handing you the words in one lump at the end. It is the same disc Ask has now, in the corner of the box it writes into, red while the microphone is open, and it is the same dictation: your words arrive where the caret is, as you speak, and you can carry on typing around them.
Two people can share a first name, and Listen has one card for the name. So the promise the other Daniel made is filed under the Daniel in your People list, and the only two things you could do about it were open the recording or press Delete. Both of those throw away a sentence that is true.
Commitments now carry the verbs a detail has always had. Reassign moves the claim to the person it is actually about, keeping its quote, its recording, its tick and anything you had corrected about its wording; Correct Wording fixes a sentence that is nearly right without moving it. Reassign is on details as well, because a fact is misfiled the same way.
The person you are moving it to usually is not in Listen yet, which is why it was misfiled. Typing a name nobody has adds them to your People list there and then, with no recording and no AI provider involved, and the promise is waiting on their page. listen context reassign <claim-id> <name> does the same from a terminal.
Delete on a commitment has always been a hide rather than a deletion, and it now says so: an Undo sits under the list on the person's page and on the review deck.
"Works at Hotspotty" names a company you co-founded and still own, and is no longer what you do. The sentence is true, the recording behind it is right, and it should not be the first thing Listen says about somebody. Until now the only moves were Hide, which throws away something true, and Correct Detail, which rewrites words that were never wrong.
Mark as Outdated is the answer. The detail keeps its wording, its quote and any correction you made to it, moves into History, and stops being fed to Ask. Mark as Current puts it back. It is deliberately a different word from Historical: that one means a later conversation proved an end date, and this one means you said so, which is a thing no conversation ever says out loud.
The label itself stays as it is. A detail can be corrected and it can be moved to another person, but "Works at" cannot be edited into "Co-founded", because those words are the extractor's vocabulary rather than yours. In this case the label was not wrong, it was stale.
Correcting a detail already offers to fix the word behind it, so the transcript, the search and next Tuesday's meeting all get it. But it only offers when it judges the edit a mishearing rather than a change of mind, and that judgement is a guess: correcting "HealthBody" to "Hotspotty" is seven letters apart where it allows three, so nothing was offered, nothing was said about why, and the transcript kept the wrong word for the next conversation to repeat.
"Fix This Word Everywhere…" is in the menu on any detail you have corrected. It asks the same question with the same preview and the same undo; it just lets you be the one who decides you were misheard.
A ticked promise used to stay on the list for ever, which turns a year of working with somebody into a column of struck-through lines with the two things still owed hidden inside it. A commitment you tick now stays put for the rest of that visit, so nothing vanishes under your finger and the tick is still there to undo, and it is behind "Show completed" the next time you open the page.
Ticking one is also immediate. It used to take about a second on iPhone, because the tap waited for the corrections file to be rewritten and for the lock that a sync pass holds on it. The check moves first now and the write follows.
The context sweep runs on a 30 second timer and took 21 seconds, so the next tick restarted it the moment it ended: 10 minutes of CPU in 12 minutes of uptime. Seven fixes, measured on a real library of 109 sources, 511 receipts, 2,379 claims, 37 people and 32,182 search entries, took a pass from 21 s to 0.46 s. End to end on the running app over five minute windows: 88% of a core before, 14% after, and what is left is a real extraction backlog.
One of those is worth stating on its own. Swift reseeds its hashing per process, so a walk that read a dictionary's values ordered receipts differently every run. Nothing came out wrong, it came out different, and the same claims carrying a different date rewrote the synced 3.5 MB people-context.json on every pass. A settled library never stopped talking to the container.
Asking for one person built a card for everybody: 97.9 s for a single card on this library. It is 1.9 s now, with byte-identical output at every step. The page was also throwing the answer away before it arrived, reloading on a signal the memory sweep posts every tick, so a card slower than a tick was never read at all.
The sidebar divider stays where you put it. The content side had a required width of 648 points that outranked the divider's own hold, so the window refused to go below 938 and every drag snapped back. The minimum is 718 now.
The page no longer says "Reported" under every detail. Attribution is set mechanically whenever the speaker was not the person the claim is about, so on the page of somebody who is only ever spoken about it was true of all of it: 45 details, 45 of them carrying a word that told no two apart. The two places that feed a model still get it, because there hearsay against somebody's own words should change the answer.
Not a crash: all 33 logs on the device for one day were the scene-update watchdog, with the main thread inside NSISO8601DateFormatter construction. Building one of those opens an ICU locale, a decimal format and a symbol table, 0.177 ms against 0.035 ms to parse with one already built, and three call sites built one per claim per receipt. They are built once now.
ellipsis.vertical is not a symbol this macOS carries and two call sites force unwrapped it, one on a person's page and one on the review deck. Both were in the day's crash reports, and both draw a to-do item. Every symbol name in the source was checked against the running system, 42 candidate strings, and that was the only missing one. A missing glyph now draws a visible fallback rather than trapping: Listen is running while somebody is in a meeting, and a glyph missing on one macOS version is not worth the recording.
Separately, uncaught exceptions thrown inside an AppKit layout pass recorded no reason at all, eight identical files saying only that it happened. The reason now goes to stderr and the exception's class and frames to activity.jsonl, and deliberately not the other way round, because a layout exception's reason embeds view descriptions and those carry the text inside your labels. That crash is not fixed, only made answerable.
Listen now reads only the calendars Calendar.app is showing. EventKit hands over every calendar an account syncs whether or not it is ticked, so a colleague's calendar delegated into a work account and unticked months ago was invisible in Calendar and at the top of the library. Today's read went from 9 events to 7, and the more interesting half is the second one dropped: a meeting in both calendars was listed twice, once with the owner's guest list and once with the delegate's. This reads an undocumented Calendar.app preference, so the failure direction if Apple moves it is showing too much rather than too little. listen calendar status names the hidden ones rather than dropping them.
A continuation offer had only the clock and the bundle id behind it, so two back-to-back Chrome calls 2m 15s apart were offered as one meeting while two calendar events, two guest lists and two far-end voices all said otherwise. A candidate that says outright it is a different meeting is refused, and listen join names the near miss and the fact that refused it.
Pressing Speaker A in one meeting could reopen the previous meeting's identity question, because a placeholder letter is unique only inside one recording.
A refusal on quota arrives naming the hour it lifts and that was thrown away, so the generic backoff walked into the same wall every few minutes: one run spent 49 of its 54 failures relearning a reset time that was sitting in the first of them. The sweep waits for the stated hour and People & Memory says so, because a sweep that stops for six hours in silence is indistinguishable from one that is broken. Reading everything still tries, in case the limit lifted early.
Two rows that are one person are now surfaced as such, with the verb following the evidence: folding away a row with no conversations is a rename that rewrites nothing, folding away one with history is a merge across every receipt that cannot be undone, and the safe case never shows the destructive word. Nothing guesses from spelling.
Notes about a person can be filed from anywhere. write_note takes a person, so Ask, MCP and the phone can add to what Listen knows, and verbatim says whose words the body is. Your own words become evidence and are quoted back with a date like any transcript line; what an agent composed is filed the same way but marked generated, stays readable, and is never read back as a witness.
The galaxy is Mac only, and so is everything that leans on it: the reveal, and the card that opens in the corner of the picture. The card builder moved into ListenKit this release so the phone shares it, and the TestFlight build going out alongside this one draws the same deck, with the periods, the timeline, the page a detail opens and the corrections it writes.
Memory still reads in the background while Listen is open, so a large library takes roughly a fortnight at the default of 40 requests a day, or one sitting with "Read Everything Now". A period you open before it has caught up shows thin cards about what was learned, while the counts and conversations are complete.
Listen remembers the people you talk to, and once a week it hands back what it learned. Memory was switched off for everybody and nothing ever asked; now setup asks, the roster lists everyone, and there is a page that gives it back to you.
Measured on a real 86-recording library: 34 named people, one enrolled, 321 pending parts against 18 processed. Consent defaulted off and the only way in was a modal reached from a person's page, so nobody was ever asked. The one enrolled person had nothing left to read, which meant the background work was finished and the queue could never move again.
Setup now asks once, with the cost stated: reading is done by the same model that answers your questions, so passages about a person are sent to that provider. Saying yes covers the people already recorded, not only the ones who arrive next. If you have used Listen before, setup does not run again, so you are asked once when you next come back to the app. Declining writes nothing and is never asked again.
Two things had to be fixed before that default was safe. The background sweep walked people alphabetically and stopped at the first with work, which is harmless at one enrolled person and a starvation bug at thirty-four: the first name spends the whole daily limit every day and nobody after them is ever read. It now serves whoever has waited longest. And a person merely mentioned in a conversation is no longer treated as having spoken in it.
Settings, People & Memory lists everybody with their backlog and a switch each, says how long the remaining work will take at the current daily limit, and has "Read Everything Now" for going past that limit in one go, priced from what requests have actually cost on your own library.
Details are grouped by what they are about rather than by the extractor's vocabulary, every line carries the date it was said, and things that were only true of one conversation, "in this session", "next week", sit under "Last time you spoke" rather than on the permanent card. The card addresses you as you rather than as "the other person". Nothing stored changes: this is how it is shown, and listen context person --json is unaffected.
View, This Week opens a deck of cards where the sidebar sits, with the galaxy beside it and the week's new conversations, people and notes arriving into the library you already had. Every card carries something to do: name the speakers in a recording nobody labelled, accept or correct a detail, open somebody you have not spoken to in months. It does not advance itself.
Two cards look forward rather than back. What was promised, in the words somebody actually used, and what you already know about whoever you are seeing next, drawn from your calendar.
A person's page has Catch Up: the same deck about them over the last ninety days. listen review and listen review --person <name> print the same cards.
Memory reads in the background while Listen is open and a large library takes a while: roughly a fortnight at the default of 40 requests a day, or one sitting with "Read Everything Now". Until it has caught up, the cards about what was learned will be thin, while the counts and conversations are complete from the first day.
There is no automatic summary of a recording yet, and the review is Mac only.
Ask takes dictation and more than one line, a correction proposed about somebody can be answered where the evidence for it is, and the tools an agent can reach now match what the window and the command line can already do.
The Ask composer gets a microphone between the model chooser and the send button. It runs the same dictation the keyboard chord runs: the same pill, the same model, the same dictionary and the same polish pass. Two things are its own, and both are about where the words land. The caret goes into the field before anything is listening, and the transcript is handed straight to the field rather than pasted, so whatever you had copied stays on the clipboard and nothing about the delivery needs the Accessibility grant.
The button shows listening only for its own dictation. Start the chord over another app while Ask is open and the button is drawn inert, because a microphone lighting up here for words going into somebody else's editor would be a lie about where they end up.
Return sends and Shift+Return breaks the line, up to six lines, after which the well scrolls. That meant replacing the single-line text field the composer was built on: on NSCell, wrapping and scrolling are mutually exclusive, so a wrapping field would have clipped everything past the cap with no way to reach the caret.
Selecting a question and carrying the pointer out of the well used to scroll the text up against the top or bottom edge of the capsule and leave it there. One line in a 52 point well is a document smaller than the thing clipping it, which is the case NSClipView does not clamp, so the offset it was offered was the offset it took. The text is pinned now whenever it fits, and left alone past the six line cap, where the document really is taller than the well and the scrolling is the point.
The card that stands in the composer's place before you have chosen something to answer with used to open on "Pick what answers your questions", then explain that Ask was on and needed an answerer. Every clause of that was about Listen's own state, read by somebody who has never chosen an AI and does not think of themselves as somebody who would. It opens on what they get instead, and signing in is a wizard rather than a claude auth login printed at them, though the command is still there under the option it belongs to, beside a button that copies it.
It is made of the system's material now as well. It drew no background at all, which read as a card only on the home page, where the drawer's panel stood in for one, and was three loose paragraphs on bare canvas on the Chats page.
Somebody asked Ask to fix a transcription and was told there was no tool for it, which was true. Auditing the rest of the MCP surface against the command line and the window found more of the same shape, so they are closed together. Seven new tools, costing 4.2 KB of per-turn schema rather than the 8 KB they would have, because the five fattest existing descriptions were trimmed first: 22,485 bytes of a 24,000 byte budget.
The dictionary is writable, split so that the reversible half is the agent's and the one-way half is not. Adding a rule changes nothing that already exists. Rewriting the transcripts behind it is apply_dictionary_backfill, and it refuses unless it carries the sentence total its own preview returned, so the write cannot be reached without first producing the lines a person reads.
The reads it was missing: provenance on get_recording, which is how far to trust a transcript; note bodies searchable through list_notes; the calendar; past Ask conversations; and how much of the library person memory has actually read. list_upcoming reports whether the calendar is authorized separately from what is on it, because an unauthorized Mac and a clear afternoon are otherwise the same empty list.
suggest_context_correction proposes a fix to something the library believes about a person and cannot apply one. That stays a decision somebody makes.
Which is the other half. A proposal told the model it was waiting for the user, and for anybody who does not run listen context suggestions that was false: proposals would have collected in a file nothing pointed at.
The proposal sits under the claim on the person's own page, because a proposed rewrite is only assessable against the quote it came from, and that is one disclosure away. Accepting it there, from the command line, or through the tool are three routes to one write. People & Memory counts what is waiting and names whose page to open.
A staged update stalls Sparkle's update cycle, and Sparkle will not look at the feed again until that one is installed, so Check for Updates was dead for as long as a version sat waiting. The menu offers the install and names the version instead, coming back to the app raises it with Install and Relaunch, and a real check at launch stops a copy that has just updated from sitting six hours behind the next release.
0.39.0 uploaded none. The release script required an environment variable that posthog-cli login does not set, so a machine that was installed and authenticated skipped the upload and reported the key as missing, which reads like setup nobody had done. Either source counts now. 0.39.0's symbols were recoverable, but only because the build directory still held the dSYM it was built with: a dSYM is keyed to the binary's UUID, and one rebuild would have ended it.
Listen says what is coming up and can prepare you for it, the whole library can be looked at as one picture, a call that was cut in two can be put back together, and searching a library of long meetings is several times faster.
The library opens on Up next: the meetings in the next twelve hours, three at most, each with the time counting down, the faces of who is coming and a camera on the ones you can join. An hour you have blocked out for yourself is listed too, because that is how most in-person meetings and every held hour are entered. An all-day event is not, and neither is an invitation you declined. When there is nothing coming, the section is not there at all.
Twelve hours rather than the rest of today, which is the obvious rule and is wrong twice a day: at 18:00 it says the calendar is empty when tomorrow starts at 09:00. A meeting stays listed for fifteen minutes after it starts, because the one you are five minutes late for is the one whose link you most want.
Open one and you get the invitation: who is coming, what the library already holds about each of them, the agenda if there is one, and every recording you have with those people. Prepare asks your agent what you should know before it starts, out of your own meetings. That conversation is not thrown away when the meeting begins: once the recording is matched to the invitation, the preparation sits on the meeting's own page rather than in History.
listen calendar next prints the same list, and then every meeting nearby that it left out with the reason. listen calendar next --prompt prints the question Prepare sends, so the window and the command are provably asking the same thing.
This is the third thing the calendar permission buys, after naming a recording and offering the people on the invitation when you name a speaker. Refusing it still costs exactly those things and nothing else, and Settings → Meetings turns the section off on its own.
View → Galaxy draws the whole library at once: your recordings, notes, people and Ask conversations on four shells around this Mac, with a line wherever the library already records a relationship between two of them. A note that names a meeting is a line. Somebody speaking in one is a line. A conversation asked about one is a line. Nothing is inferred: there is no similarity edge and no "these happened the same week" edge, so every line is a row you can go and read.
Distance from the centre is the kind of a thing and nothing else, not how important it is or how recent. Click a star to see what it is connected to and open it; double-click to go straight there. The card names the star's links as links, so following one is a click. The picture is drawn from what is already on this disk and reaches no network.
You are the centre, once the library has heard you speak: one star rather than a hub on the people shell and an empty planet in the middle. Click a shell in the legend to strike it out and take it off the picture, and searching in the sidebar narrows the picture to what matches and what that connects to. The globe in the title bar opens the galaxy, the globe on a page opens that page's own star and the cross brings you back to where you were, and Settings → General turns the whole thing off.
It runs the GPU while it is open and stops on its own when the window is hidden or covered, under Reduce Motion and in Low Power Mode.
The window takes a deep blue-black rather than the system grey, so the galaxy sits in the same temperature as everything around it instead of against a seam.
The strip of meters along the bottom of a live recording came with it. It was a translucent panel bolted to the foot of the page, blurring nothing, because nothing sits behind it: measured at 28,30,37 against the page's own 11,15,28. It draws the page's ground now.
If a recording stops part way through a call and you start another one, Listen now offers to put them back together. The later recording's page says which meeting it looks like the rest of and why, in the terms you can check yourself: how far apart they are and whether both were the same app or the same calendar event. Merge recordings folds it into the earlier recording and Not now leaves them alone, because starting a second recording on purpose is an ordinary thing to do.
The earlier recording is the one that survives, so the meeting keeps its start time, its calendar event, and every note and conversation already pointing at it. The time between the two halves becomes silence rather than being closed up: a joined recording is a timeline, and closing the hole would move every word after it earlier.
listen join <id> [--into <id>] does the same from the command line, and prints what it would do without changing anything until you add --apply.
Turn Ask on before choosing something to answer with and Listen shows a card where the composer would be. It used to lead with "Pick what answers your questions" and explain that Ask was on and needed an answerer. It now leads with what you get: ask your conversations anything, what did we decide, where did that idea come from, and every answer linked back to the moment it was said. One button to set it up rather than two of equal weight, and the way out is the round cross in the corner that the rest of the window uses.
If a CLI is installed and signed out the card says so in a sentence and hands you to setup, instead of printing a terminal command at you. The command is still in the wizard, under the option it belongs to, with a button that copies it.
./install.sh now refuses to quit and replace a running copy that is in the middle of a recording, and says so. This is fixed because it happened: a build installed itself eleven minutes into a call, and the 97 seconds between the two halves of that meeting are simply gone. LISTEN_INSTALL_FORCE=1 overrides it.
Every keystroke re-read and re-decoded every transcript on disk, and a one-letter query built a match for each of the hundreds of thousands of places it occurred in order to show one line and a number. On a library of 120 hour-long meetings the first letter cost 616 ms and each one after it 380 ms, and the list was rebuilt two or three times per keystroke. Transcripts are now kept in memory and checked against the file, a recording is rejected in one pass before its turns are walked, occurrences are counted rather than collected, and the field's delayed action no longer redoes the query it has already done. The same typing costs 111 ms for the first letter and 88 ms after it.
LISTEN_LIBRARY.Summaries about people now reach your iPhone reliably, and two Macs no longer overwrite each other's setting to get there.
Each Mac published the summary model it offers into a single shared setting whose value named the Mac that wrote it. Two Macs with different Ask selections could never agree, so each rewrote the other's every few minutes, indefinitely. Measured on a two-Mac library on 9 September 2026, the value changed hands roughly every four minutes all evening, and every change was a write to iCloud from both machines.
Each Mac now advertises on its own record, so two Macs offering different models are two facts rather than one contested slot. listen sync inspect shows what each device is offering beside what it holds. No iCloud schema change was needed and nothing has to be reconfigured.
Library-level files are announced in the change feed once. A pull that failed, was throttled, or died with a suspended app let the announcement pass and nothing offered it again, so an iPhone could sit indefinitely believing no Mac had ever offered to run summaries while every sync reported success. Those files now carry a debt that the next pass settles, and a file that cannot be taken twice running is reported instead of being silent.
Requests and other things you have just done are also sent at the start of a sync rather than after the whole library has been walked, which is the difference between leaving in the first second of a pass and not leaving at all when iOS suspends the app part way through.
The iPhone can name a preferred Mac. It is a preference and not a lock: if that Mac is asleep it is still the one asked, the screen says when it was last seen, and the Mac that is awake is offered rather than substituted, because two Macs can be on different models and different providers. A request still waiting can be handed to another Mac, and only while no Mac has claimed it.
Speaker labels are now a way to review a conversation, not just a way to rename somebody, and long transcripts no longer build every paragraph before showing the first one.
Click a speaker label and Listen opens a persistent Speakers panel beside the transcript. It shows everybody in the recording, how much they spoke, and whether they have been identified. From there you can identify or change the selected person, play only their clips, or show only their transcript turns.
The same actions are in the label's right-click menu, including for an unidentified speaker. The old “Who is this?” dead end is gone. Showing one speaker hides the other transcript turns and the main play button continues through that speaker's clips; “Show all transcript” restores the conversation and its previous reading position. Escape backs out one step at a time.
Ask is temporarily hidden while speaker review is open. The speaker panel uses the full height instead of competing with a question box that belongs to a different task, and it comes back as soon as review closes. Speaker colour dots also have more room around them.
The transcript is now a variable-height, virtualized list. AppKit creates the paragraphs near the viewport as you reach them instead of constructing the entire meeting before drawing the first frame. On a scratch copy of a 469-turn, 1 hour 16 minute recording, 17 rows were materialized initially and warm first render fell from 879 to 1,182 ms before this change to 109 to 193 ms after it. One cold launch measured 384 ms.
Speaker totals are cached until their transcript file changes. A person page loads recordings 24 at a time, and a long saved Ask conversation initially draws its latest 40 messages with an explicit way to load earlier history.
Listen remembers the people in your meetings, and a deleted recording stays deleted.
A person's page is no longer a list of their recordings. Listen can now build a summary of what it has heard about somebody, with every detail carrying where it came from: which recording, which speaker, when it was said, and when it became true. Corrections you make survive a rebuild, and so do the things you pin, hide or exclude.
It is off until you ask for it, per person. Nothing is generated in the background for anybody you have not switched on, adding a person never calls a model, and there is a global pause plus a daily limit for when it is on. The summaries use whichever Ask provider and model you pick at the time, so this needs Ask set up; the rest of the page does not.
You can also add a person before their first recording, from the home screen or an empty People search, and a name you type is merged with the speakers in your transcripts rather than becoming a second identity beside them. Manual profiles sync between your Macs.
Searching people is local: keywords and Apple's on-device semantic search, with an optional multilingual model if you want to download one. Ask, library search, the CLI and MCP all read through the same retrieval, including asking what Listen knew at a past date. Your iPhone receives an encrypted summary; raw transcripts, vectors, jobs and credentials stay on the Mac.
The dictionary pane used to ask which matching mechanism a word wanted before it would accept one. That is a question about Soundex, not about the word, and getting it wrong failed silently. On a real library one term had fired 19 times while five hand-written corrections for the same word had fired 9 between them, and three of those five had never fired at all. The counts existed the whole time and nothing showed them.
Now there is one row per word, with its spellings and how often it has fired, and adding one tells you which mechanism it chose. A new word can also correct the transcripts you already have: it previews what it would change, and only does it when you say so.
Running that preview over 75 real transcripts is what found something worse. The sounds-like matcher had been rewriting ordinary English: "and it knows the email address" became "and it Kinsight email address", and with a Beehiiv term in the list "Bye-bye." became "Beehiiv." in 17 recordings. Soundex is lossy enough that those code identically. A match now has to look like the term as well as sound like it: 59 proposed rewrites before the guards, 58 after, and the one that went was the destructive one.
Your iPhone applies the dictionary's exact spellings too, so a name you taught Listen is spelled right in the transcript the phone writes while your Mac is asleep. The sounds-like half stays on the Mac deliberately, because it depends on a system word list iOS does not have, and running it there with the guards off is worse than not running it.
Delete a meeting on one Mac and it could come back. It needed a second device that was asleep when you deleted, had something of its own to send about that recording, and woke up before it had heard the news. It found nothing in iCloud where the recording should be, decided the recording was missing rather than deleted, and put it back. Every other device then pulled it down again.
It happened on 7 September. Five recordings were deleted at 11:55, the second Mac opened at 11:56 with freshly arrived audio for three of them, and those three had to be deleted a second time at 12:03. Nothing on either machine said anything was wrong.
The cause is that a deletion was never written down. It was the absence of a recording, and an absence has other explanations: a drive that did not mount, a library restored underneath the app, a folder moved in the Finder. Listen had to guess which one it was looking at, and a guess is the wrong tool for something that cannot be undone.
So a deletion is now a fact Listen records and sends, the same way it already records being asked to forget somebody's voice. Every device reads that list before it sends anything, so a Mac that has been closed for a week obeys the deletion instead of arguing with it. A device holding an edit nobody has seen yet also obeys it, and tells you what it set aside. A recording that simply goes missing from the disk now deletes nothing anywhere, which is the half that used to need a guess.
Deleting something already left your other devices a copy for a fortnight, and the device you were sitting at threw its copy away at once. That was backwards, since the device you are sitting at is where you notice the mistake.
Every device keeps it now, and there is a way back:
listen sync trash --restore <recording-id-or-note-name>
It puts the files back and tells your other devices to do the same. The confirmation dialogs say that rather than saying it cannot be undone, and listen sync deletions lists what Listen believes was deleted.
Deleting a voice memo on your iPhone had a second version of the same problem. The phone offers your Mac any recording the Mac does not appear to have, so a memo you deleted was offered again fifteen minutes later, and again after that. The Mac now recognises one it has been told to delete and declines it.
Short recordings get names too.
A nine-second memo showed A and stayed that way for ever. Listen would not put a name to a voice it had heard for under fifteen seconds, on either device, so a quick note to yourself was the one recording it never recognised anybody in, and no amount of waiting for a Mac helped: your Mac applied the same rule.
The rule was one number doing two jobs. Being sure enough to remember a voice and being sure enough to ask who it is are different questions, and the expensive one had been answering both. Now they are separate. What goes into the voice bank as a reference still needs fifteen seconds and has not moved a millimetre, because a shaky identity in there quietly recruits the next one. Asking who somebody is needs five.
Measured before changing it, over every named voiceprint in a real 23-person library. Under five seconds the closest match was wrong both times it came up. At five seconds and above it was right every time, and everything confident enough to be applied without asking was correct. The two names in that library that were applied wrongly came from recordings of five and seven minutes, so length was never what separated a right answer from a wrong one.
A wrong name here is cheap and visible in a way a wrong reference is not: it is marked as the bank's guess, it never becomes evidence, and it is one tap from being corrected on your phone or one listen label on your Mac.
listen voices --repair puts a voiceprint back under the name its transcript uses. It could not see a print filed under your own name, which is where the worst mislabel in this library was hiding: five and a half minutes of somebody else's voice, filed as you, teaching the bank that you sound like them.
It also could not see a swap. The search looked for a name with no voiceprint and a voiceprint with no name, so it needed something missing to aim at. Two prints simply the wrong way round leave nothing missing, and the bank is confidently wrong with no gap to point at it. It now also asks the other question, whether a voiceprint sounds like the person it is filed under, and refuses to touch one that already does.
Your iPhone knows who is speaking.
Listen learns voices on your Mac, and until now that is where they stayed. A recording made on your iPhone showed A, B and C until a Mac woke up, claimed the audio and named everybody, which could be an hour or a day.
The voices travel now. Your iPhone holds the same bank, sealed with the same key through the same private container, so a conversation you record in a kitchen has people's names on it within a minute of it ending. Measured on a real library: a two-minute room recording, the phone's own separation, names applied at +0.89 and +0.84 confidence against voiceprints made on other days in other rooms.
It travels both ways. A voice your phone hears first reaches your Macs, so somebody you met while your laptop was shut is somebody Listen knows afterwards.
Nothing is guessed twice. Every name the phone applies on its own is marked as the bank's guess, and a guess is never the evidence for the next one. Where two devices have heard the same conversation the Mac's pass wins, because it had the separated tracks and the time.
Say who somebody is, from your phone. Tap a letter in a transcript your iPhone read and name the person. That is the one thing on the phone the bank treats as a person's word rather than a guess, and it survives: the Mac carries it onto its own transcript of the same conversation instead of writing over it.
It is a switch, and off means gone. Recognise voices on this iPhone, in Settings, on by default. Turning it off deletes the voices from the phone rather than hiding them, and stops it being sent any more.
A recording your phone had already read still said "Waiting for your Mac" under it, with a clock beside it, which is the same thing the app says about a recording nobody can open yet. The transcript was one tap away and half the speakers were named. Rows say what is true now: Read on this iPhone, or Read here, your Mac is redoing it, quietly, with the type lined up rather than pushed sideways by an icon.
Tap a speaker's name in a transcript to open their page: every recording they are in, how long they have spoken, and a way to ask about them.
The Library filter sheet had tags and nothing else, and choosing between recordings, notes and people meant starting a search you did not want. That choice is in the sheet now, with a count beside each.
listen calibrate on a library that has grown past its measured thresholds now has somewhere to point: .agents/notes/speakers.md records what a merged voiceprint from an older pipeline looks like and how to find one.Listen asks which languages your meetings are in, and your iPhone reads its own recordings instead of waiting for a Mac.
Setup has always asked this, and the answer used to be two radio buttons standing in for two models: English only, or English and others. It could not say which other language, so nothing could use it and nothing kept it.
It is a list of languages now, prefilled from what this Mac is set up in, and the answer is kept. Three things need it. Apple's engine has to be told a language before it decodes and cannot guess one. Your iPhone has to know whether it can read a recording at all. And a transcript that comes out thin is only evidence of the wrong model if you speak something else.
Settings, Models asks the same question and says what your answer means. It does not switch models for you: v3 reads 25 languages and loses about 4 in 10 mentions of names like Claude, WhatsApp or ChatGPT, so which side of that you want is a decision rather than a setting.
Needs iOS 26. A recording made on the phone used to be unreadable until a Mac was awake with Listen running, which can be hours. It is now transcribed on the phone the moment it ends, with Apple's on-device speech, and the voices in a room are split into A, B and C.
If iOS stopped the app in the middle of a recording, the audio was on disk and the app could not see it: a recording was only published when it stopped cleanly. Anything a previous run left behind is published at the next launch instead, with its length read back from the audio.
The thing that was stopping those captures is fixed too. A catch-up pass could pick a recording it was unable to read, decline it, and pick it again immediately, for ever. On a locked phone that spent enough of the processor for iOS to kill the app, taking the recording with it.
listen transcribe --model apple reads a meeting with Apple's engine on macOS 26. It is not offered in the window and is not the default: measured over 12.9 hours of real meetings, it finds 71 of the 94 domain proper nouns Parakeet v2 finds.A speaker you have named keeps their voiceprint when you have a second Mac.
Renaming a speaker writes the name into two files: the transcript, and the voice bank that lets Listen recognise that person in later meetings. The transcript kept the name. The bank did not, if you have a second Mac.
Every per-recording file syncs with a record of what both devices last agreed, which is what tells "I edited this" apart from "I am behind". The voice bank was the one file without it, because it travels in a zone of its own so that a phone never receives a voiceprint at all, and that separation quietly took the agreement record with it. Whichever Mac wrote last won, so a second Mac that had not seen the rename pushed its old bank back over it.
Nothing about it looked like a defect. The transcript still said the right name, so what you saw was Listen failing to recognise somebody it had already been taught. Measured on the development library: 27 of 60 recordings held a voiceprint under a label no transcript used, and 10 people were missing from the bank entirely.
listen voices --repair prints what it would fix and --apply fixes it, and it is worth running only once every Mac on the library is on this version: before that, the other one can still put the old bank back.A meeting whose transcription was interrupted no longer says it is still being transcribed for ever, on this Mac or on your iPhone.
Listen writes a meeting's transcript and then writes down that the run finished. Anything that stops the app between those two steps, a quit, a crash, or an update installing itself, leaves a recording that has its transcript and still claims to be working on it. The queue could never recover it: what it looks for at launch is a recording with audio and no transcript, and this one has a transcript.
You would not have seen it here. Every screen on the Mac derives the state from the files rather than trusting that field, so a finished meeting looks finished. What that could not fix is the copy sent to your other devices, so an iPhone showed "Transcribing on your Mac" under a meeting whose full transcript it was already displaying, and kept showing it.
Found by installing 0.32.0, which interrupted a transcription to do it.
A recording made on an iPhone now reaches your Mac without anybody keeping an app open, one stalled transfer no longer stops everything else syncing, a meeting spoken in a language the English-only model cannot read is read again by one that can, and voiceprints the library had lost the name of can be put back.
A 45-minute voice memo sat for a day under "Retrying sync: Audio is not available in iCloud yet". The sentence was true about iCloud and pointed at the wrong place: the audio had never left the phone.
An iPhone reports every recording whose audio is on its own disk, because that is what lets a Mac tell it when it is safe to let go. A Mac read that as "there is a copy in iCloud to fetch", asked, and got nothing, because a phone deliberately never publishes one: the Mac that receives the recording publishes it instead, so that a conversation is not sent up twice. That question was asked on every pass, on every Mac, for every phone recording waiting to arrive.
This half needs the iPhone app updated as well. The two changes are a pair: the phone's is inert without this release and this release is harmless without the phone's.
The phone used to send a recording's audio only while Listen was open and on screen, and any interruption threw away everything sent so far and started again from zero. A 45-minute memo is 87 MB, so locking the phone in the middle of one meant it never finished. The transfer is now handed to iOS itself, which completes it in the background across app switches, a locked screen, and the app being closed.
New recordings stopped appearing on a Mac until the app was quit and reopened. A sync pass is allowed to run one at a time, and nothing in Listen ever set a time limit on a network call: CloudKit's own default for a file transfer is seven days, so one transfer that stopped moving held that slot for as long as it liked and every later pass was dropped and forgotten.
An English-only decoder handed another language writes fluent, confident, invented English and reports success, which leaves no trace anywhere. Asking the transcript what language it is in answers English at 0.994 to 1.000, because every word in it is an English word.
How thin the transcript is can be asked instead. Words per second of carrying audio: five Dutch calls score 0.37 to 0.47, forty-one English recordings score 1.11 to 5.24, and the midpoint is 0.79. Below that, Listen reads the meeting again with a model that reads 25 languages, and never downloads one to do it.
Setup now asks which languages you meet in rather than which model to use, since it downloads one and the wrong answer is silent. The multilingual model did not become the default: over six English meetings it finds 38 of the 62 domain proper nouns the English-only one finds, turning Claude into "cloud" and WhatsApp into "what's up".
Reported as a question: a meeting was re-transcribed and the speaker labels did not come back. Measured across the library afterwards, 27 of 60 recordings held a voiceprint under a label no transcript used, and 10 people were missing from the voice bank entirely. Nobody reports that, because it does not present as a defect. It presents as the voice matching being mediocre.
listen voices --repair prints what it would do and --apply does it, the same shape calendar backfill uses, because it rewrites the one file a recording cannot regenerate. Anything with more than one candidate on either side is skipped: a name with no voice is better than somebody else's voice under your name. On the development library that was 19 repairs and 10 people back.
The anonymous usage statistics gained events about sync, because none of the problems above were visible in them and all of them had to be found by reading code. What is added is how large a transfer was, how long it took and where an interrupted one stopped, how long a recording has been waiting, and how long the app took to open. Sizes in rough buckets, and the kind of device holding a recording rather than which one. Still never recordings, transcripts, titles or names, and still one switch in Settings, Privacy that turns all of it off. TELEMETRY.md is the complete list.
A webinar watched on speakers no longer puts its hosts in the transcript twice, a recording whose microphone never opened now reaches your other Mac, and a long meeting title stays clear of the toolbar.
Watching a webinar on speakers with the microphone open put both hosts in the transcript twice, once under their own letters and once under your name. Muting yourself in the meeting app stops the far end hearing you and does nothing to Listen, which records the microphone raw, so the hosts came back in through the speakers and were transcribed as you.
Listen already dropped that on a recording it reads as a room. It could not on one it reads as a call, which is what a webinar is, because there it labels the whole microphone track as you without looking at it.
The worse half of the same bug, and the invisible one. Listen learns your own voice from the microphone track, so on that webinar it learned the host's. The voiceprint filed for you sits at cosine 0.7477 from the host, where the meeting's two real speakers sit at 0.1226 from each other, and 0.75 is the point at which Listen names somebody without asking. The only thing that kept it out of the voice bank is that a print needs 15 seconds of speech before it counts as evidence and the bleed lasted 13.4.
A recording whose microphone held nothing but the far end now files no voiceprint for you at all.
This does not repair a recording you already have. The duplicated lines and the voiceprint stay until you remove them, and listen label <id> Me --discard does both, keeping any names you have already applied. There is no route to it in the window yet, because the microphone track is never treated as a placeholder and only a placeholder can be discarded there.
A call whose microphone never opened leaves a mic.wav that is a 44-byte header with no audio behind it. Building the combined file the other Macs sync failed on that empty side, and failed again on every pass afterwards, so the recording never crossed: the other Mac, told by the heartbeat that this one held the audio, sat on "Retrying sync: Audio is not available in iCloud yet" for a day with the whole transcript on screen under it.
The empty side still counts as a track, so the file splits back into the two it was captured as rather than putting the far side into everyone's microphone track. Measured on the live library: "sent audio for 1" on the first pass, "got audio for 1" on the other Mac 75 seconds later, a 22.0 MB master of 1331.39 s against the metadata's 1331.365.
The window's toolbar floats over the page, and the title sat 38 points down on the reasoning that it is left-aligned while the record capsule and the ellipsis are on the right. That holds only for a short title. A long one fills the width and ran the whole way under both: measured off a screenshot at 2x, the capsule's bottom edge is 39.5 points below the top of the window and the title's frame began 1.5 points above it, with only the text field's own leading keeping the letters out of the button. It is 52 now, which puts the frame 12.5 points clear and the capital letters 17.5.
"Ask about your library below" pointed at a composer that is not there when Ask is off. That branch now offers New Recording, which is the one action actually available. The empty-library copy said to start a recording from the sidebar, which has been wrong since the record control moved to a toolbar button.
Conversations about a meeting get a tab of their own, the starter questions stop offering one that was never true, and pressing Stop during a call no longer starts the next recording.
The questions you have asked about a meeting used to be links in a line of small text under the tab bar, mixed in with any notes an agent had written about it: "Also about this: Weekly summary, What did we settle on the trial length?". Two links that look the same and do different things, in a run of text that became a paragraph once you had asked five questions.
Chats · 2, the way the Notes tab does, so a meeting you have already asked about does not look like one you have not.Clicking an answer's working-out open to read it visibly moved the line that opened it, and closing it again briefly overlaid that same line with the paragraph sliding away underneath. Both were the disclosure's own animation catching content it should have left alone; the line stays put now, either way.
A card with a conversation in it has always carried the conversations about that page under its title. A card with nothing in it yet had no title and no route to them at all, so a meeting you had asked about last week could not tell you so until you had asked about it again. History now sits at the right of the chips row and opens the same menu.
Pressing Stop while the meeting was still running left the detector armed against the call it had just stopped recording, so about three seconds later it started a second recording and asked about that one, and stopping that started a third. Stopping by hand now suppresses whatever is on a call at that moment, and re-arms when the app leaves the call, which is the rule "Not now" already followed. A meeting that ends on its own is unaffected: nobody is on a call by the time it stops, so nothing is suppressed and the next meeting is detected normally.
Nothing about how conversations are stored changed. They are the same chats/*.json files, and the conversation list reached from the home page still shows all of them across the whole library; the tab is a narrower view of the same set.
The note and the transcript are tabs on a recording's page rather than two sections stacked one above the other.
You can no longer read a note and the transcript at the same time, and playback stops when you switch to Notes. The transport belongs to the transcript, and a player that is not on screen is one you cannot pause. That is the trade for a note with the whole window and a transcript that starts at the top.
Nothing about how notes are stored changed. They are the same markdown files in the same folder, and the CLI, the MCP server and an agent read and write them exactly as before.
A WhatsApp call taken on the MacBook's own microphone recorded the other side and none of you. This release records you, says so when it cannot, and plays the recording that was left behind.
The moment a call connects, macOS switches the built-in microphone from its usual processed mono stream to the raw three-microphone array, for every app on the Mac, and keeps it there until the call ends. Listen could describe one or two channels and threw on three, four milliseconds after opening the device. Nothing tried again, because every retry in the recorder only ran for a track that had started. So the microphone track was a 44-byte file, the strip for your voice stayed flat for 22 minutes, the status line said "Recording from MacBook Pro Microphone", and the transcript came out as one speaker at 99%. The empty file then broke playback of that recording as well: play opened at 00:00 / 00:00 over a perfectly good far-end track.
A call taken on a headset or a USB microphone was never affected, which is why the earlier calls in a library are fine.
Your side of a call recorded before this release is gone: the file holds no samples. The other side was recorded and transcribes as before. And a far end that says a single syllable in a twelve-second call will still come back with no words, whichever model, because the recogniser will not commit to one syllable in that much silence.
./verify_capture.sh --ui plays a phrase through the speakers and records it in each of these states, including the three-channel one, which tools/vpio.swift reproduces without making a call.
Searching your library found the right meeting and then left you to hunt through it by eye. This release makes a result say what it found, and adds a way to search the page in front of you.
Typing a word you remembered hearing returned a row with the meeting's name on it and nothing else. Nothing said whether it matched the title or minute 26 of a 38 minute call, how many times it appeared, or where to start reading. The search had already located every one of those and was throwing them away.
A result now carries the sentence that matched, with who said it and when:
Call with Joris Goossens 8 Saturday · 15:27 · 41:30 Maxime 15:52 …doen. Ik heb een iPhone, dus dan heb je…
The number on the right is how many times the word appears in that recording. Notes are excerpted the same way. A recording that matched only on its title gets no excerpt, because repeating the title underneath itself says nothing.
Cmd-F now searches the page you are looking at, over its title, its note and its transcript, with a counter, next and previous, and Return and Cmd-G to step. Every match is highlighted, the current one more strongly, and the waveform marks where in the meeting they are, so a word said three times in an hour is three ticks on the scrubber. It works on a note's page too.
The library search field has moved to Cmd-Shift-F. This is the one change here that will interrupt something you already know how to do. Cmd-F means the document in front of you in every other Mac app, and the library field is on screen permanently and one click away, so it is the one that can afford the longer chord. It is the same pair as Xcode's find-in-file and find-in-project.
Clicking a search result opens the meeting with the find bar already up on the first match, so the word you typed carries through instead of being abandoned at the door.
Conversations you have had with an agent are searched too. They are not listed in the library, because they are not a collection of it; a row at the foot of the results says "See 8 chat results" and takes you there with the word already in that screen's own field.
Pressing "Notes" or "Recordings" above a set of results used to narrow the list to that kind, and hovering one lit its background. A heading is set in heading type above a hairline, which reads as a label, so this was a control hidden inside something that does not look like one. Both other ways in are unchanged: "Show only" in the magnifier at the left of the search field, and typing kind:notes or is:notes.
The count on a result row and the count in the find bar can disagree in two cases, and both are honest rather than broken. A word spanning the gap between two paragraphs matches the list and not the page. And an untitled recording matched on the word "untitled" is matched on the placeholder the list draws, which is not text the page contains. Either way the bar opens and says it found nothing on screen.
Find in page covers meetings and notes, not a person's card, which is mostly counts and chips rather than prose. On a meeting it searches the note that is on screen rather than every note attached to it.
Searching is fast enough not to need throttling: measured on the longest transcript to hand, 156 paragraphs, a single character finds 2546 matches and redraws them in 2 ms, so there is no delay before results appear and no minimum length before it starts.
Listen could lose the other person's half of a call and tell you nothing about it. This release does not fix every cause of that, but it does mean you will know while it is happening instead of finding out from the transcript.
The system audio track, the one that records everyone else, can stop receiving audio while the recording carries on. The file keeps growing, the duration is right, the microphone track is perfect, and the meter on screen draws a flat line that looks exactly like somebody listening quietly.
Measured on three real meetings: one 38 minute call has audio from the other side for 12.6% of its length, with 21 whole minutes of pure silence, while both people were talking normally and neither could hear anything wrong.
Listen never checked, and the reasoning for that was written down and looked sound: a silent system track is the ordinary state of a Mac playing nothing, so "the track is quiet" tells you nothing. What that missed is that a broken capture is silent in exactly the same way.
Listen now tells the difference, by asking whether the silence is punched through audio that is otherwise arriving, which nothing in a working audio path ever produces. When it happens you get a sentence on the recording screen and on the floating panel, saying what is missing rather than showing you a meter to interpret:
Listen also rebuilds the capture on its own when it sees either, and pads the gap so the two tracks stay lined up and nothing after it is attributed to the wrong person. If that happens the screen says so too, and says how many times.
One related fix: the capture was tied to whichever output device was in use when the recording started, so putting headphones on mid-meeting moved the sound to a device Listen was no longer listening to. It follows the change now.
listen audio --check
with no arguments looks at your recent recordings and says how much of the other side arrived, how much of it is damaged, and which silences are long enough to have cost you words. Add a recording id to check one. It exits non-zero when it finds something, so it can be scripted.
This is worth running once on your back catalogue. It cannot repair anything: audio that was never captured is gone, and the only thing to do with an affected recording is know not to trust its transcript.
The underlying cause is not established. Every failure measured so far happened with Bluetooth headphones as the output, and a Bluetooth route does measurably tear where the built-in speakers do not, but the effect reproduced in testing is about a hundredth of the size of the real ones. Chrome's own audio pipeline is the largest untested difference between the two.
So this release is a detector, a repair attempt and an honest report, not a guarantee. If you are recording something that matters and you have the choice, a wired output or the built-in speakers is still the safer setting.
Almost entirely about the anonymous statistics, and most of it is correcting things this project told you that turned out not to be true. Nothing here changes what leaves your Mac. It changes what you can see about it, and what the documentation claims happens to it afterwards.
Settings, Privacy has always said your statistics travel under a random install ID that is created when you switch it on and deleted when you switch it off. It now prints that ID underneath the switch, so the sentence can be checked instead of believed: turn the switch off and on again, and the ID that comes back is a different one.
listen telemetry prints the same ID, along with where the data goes and which version of the dictionary is in force. That exists for a Mac you reach over SSH, which has no settings pane to click. It also says which of three reasons applies when nothing is being sent, because from the outside they look identical and each is fixed differently: an organisation's device profile turned it off, you turned it off, or this is a build nobody released.
This is also the only way to tell one of your own machines from a stranger's in the statistics, because no event carries a device name, deliberately.
Both were found by checking the analytics project against what TELEMETRY.md and the privacy page said about it, rather than by reading the code that enforces the part of it Listen controls. The send filter itself was correct: an audit of every property that has ever arrived found nothing outside the published list.
Retention. Both documents said events are kept "for at most 12 months". Nothing was enforcing that, and nothing could: PostHog has no way to delete events after a set period, on any plan, through any setting or any API, and the request for one has been open since 2023. Both documents now say events are kept indefinitely. The identity is the part that does get deleted, on your instruction and at once, which is what turning the switch off does.
Location. TELEMETRY.md said location is "kept only as a country". Your IP address is genuinely discarded and has never been stored, but a city and a postal code were being worked out from it first. Those are now switched off. What still arrives is a continent, a country, a region, a time zone, and a latitude and longitude accurate to that region rather than to you. TELEMETRY.md now describes that instead.
The dictionary version is now 3.
Activation could not tell a new install from an existing one, because the one-time migration that turns statistics on fires the same event for everybody who updates. It now says which it was. Setup could not see somebody closing the window part-way, so an abandoned setup was missing rather than recorded; it now reports that it was abandoned, and how far it got. And the speech model was reported as "unknown" for any recording transcribed with the default, which was most of them; it now reports the model that actually ran.
The download buttons on the website now record that they were pressed, and which of the four on the page it was. Still cookieless, still nothing stored about who did it, and the privacy page says so.
Four fixes, all of them found by installing Listen on somebody else's Mac for the first time and watching. One of them changes where Ask lives, and it is the one to read first if you use it.
Recording and transcribing need nothing configured. Ask needs a CLI you have signed into, or a URL and a key, and until that is done there is nothing for it to do. What it added to a first run was a question box that could not answer, a card explaining why, and a Chats screen with nothing in it, on top of a library that had no recordings yet either. The card was the largest thing on the home screen before there was a single recording.
So it is behind a switch now, in Settings, Ask, and the switch starts off. With it off there is no question box, no Chats in the title bar and no card anywhere. With it on, all three come back exactly as they were.
If you already use Ask, this update turns it off and you turn it back on once. That is deliberate rather than an oversight: taking a working agent as evidence you had chosen Ask would put words in the mouth of everybody who never did. It is one checkbox, and your conversations are all still there.
Setup now has a step for it, after Dictation, which says what Ask is for before it asks for anything and has a Not now that costs nothing.
The card you see when Ask is on and nothing is answering yet has been rewritten. It no longer sits above a question box that cannot be used, it has two buttons rather than three, and Not now puts Ask away rather than only hiding the card. Two layout faults went with it: its heading was being clipped in half by its own top edge, and its last line was being cut off.
A call under about thirty seconds lost whoever was on the far end. Not garbled: absent. The transcript held your microphone alone, under one speaker, and read as though you had been talking to yourself.
Two thresholds decided whether the other end of a call was worth transcribing, and both were plain second counts measured on a 47-minute meeting. A nine second recording cannot contain thirty seconds of speech, so on anything short they answered no whatever the audio held. Measured on a 9.5-second call between two people, the far end was three of its ten seconds, was loud, and was dropped before anything looked at it.
They are fractions of the recording now, with the old counts as a ceiling, so nothing about a long meeting changes. Checked across 48 recordings from 37 seconds to just over two hours: none of them changed its answer.
If you have short calls already in your library that came out with one speaker, Transcribe Again on them will now find both. It replaces the transcript, so hand corrections on those recordings go with it.
Downloading the speech model could reach very nearly the end, drop to 0% · 41 KB of 2,47 GB, and stay there. Nothing was actually lost, and pressing Download again in Settings finished the job, but there was no way to know that from the screen.
The bar follows the transfer through a pause now, and never counts backwards. Reported once and fixed from the evidence rather than reproduced, so if you see a download stall again, the byte count on that screen is the thing worth photographing.
The dictation shortcut opened the microphone inside the keyboard event handler, so a slow input device delayed every keystroke on the Mac until it was ready. One wedged USB microphone measured 5.1 seconds.
An Ask panel that opens over a meeting and will not close was reported on 0.24.1 and is not fixed. A related fault in the close button was found and corrected, but three attempts to reproduce the reported one all failed, so it may still be there. With Ask off, which is now the default, it cannot happen. If you hit it, what would help is whether the panel covered the whole meeting page and what you pressed just before it appeared.
One fix. Discard Recording did nothing when it was pressed, and had done since 0.10.0.
It is the only destructive item the ⋯ menu offers while a recording is running, and it was wired to the wrong object: the menu's items are addressed to the library window, and throwing away a recording in progress belongs to the part of the app that owns capture. macOS validates a menu item against the object it is addressed to, found nothing there that answered, and disabled it. A disabled item is normally greyed, which would have shown; this one is drawn red because it is destructive, and a coloured title keeps its colour when an item is disabled. So it looked exactly as available as it does when it works, opened with the rest of the menu, and did nothing at all when clicked, with no error and nothing written anywhere.
It now asks "Discard this recording?" the way it always meant to: capture stops, the audio is deleted, and notes you typed during the call are kept under Notes in the sidebar.
On 0.24.0 or earlier and want a recording gone now: press Stop, select the row and choose Delete. It asks the same question, deletes the same audio and keeps your own notes the same way.
Two things: the model that will read a meeting can now be chosen while the meeting is still running, and a person's card says what it can be asked.
Parakeet v2 is the default and it only reads English. Handed a call in another language it does not fail or warn: it writes fluent English sentences that nobody said, and the first sign anything went wrong is somebody reading the transcript. The only control over that was Transcribe Again, which comes after an hour has already been read once and is paid for by reading it a second time.
The recording screen now names the model on the row that names your microphone, at the opposite end: "Parakeet v2 · English only". Click it at any point during the call and pick "Parakeet v3 · 25 languages", and that is the model Listen uses when you press Stop. The coverage is in the button rather than only in the menu, because the fact worth acting on is the second half. The same list is under Transcribe With in the ⋯ menu while a recording runs, which is the only item that menu offers mid-call besides Discard.
Nothing is transcribed or downloaded until the meeting ends, so it costs nothing to change your mind, and the choice stays with that recording the way Transcribe Again's does: a later re-run uses it too. If the model you pick is not on your disk, the menu says what it will cost to fetch, and the fetch happens when the meeting is over rather than during it.
Checked on a 41 minute Telegram call held in Dutch: chosen while it ran, transcribed once, by v3. Parakeet v3 works out the language as it goes, so a mostly-Dutch call can still come out with the occasional line decoded as English; that is the model, and it is still the difference between a transcript with mistakes in it and one that was invented from end to end.
The composer on a person's card opened as an empty field. The library screen and a meeting page each offer four starter chips there; a person offered none, on the argument that a card with somebody's name at the top has the question in it already. It does not: knowing who a pane is about is not knowing what it can be asked.
A person's card now offers Catch me up, Open items, Next call and Their views. They are the four questions only a person makes answerable: what you have talked about lately, what is still outstanding in either direction, what to raise before you speak to them again, and what they think about the subjects that keep coming back. Each one names them in the question and asks for the meeting behind every claim, so an answer can be traced to the call it came from.
This release is what the first install on a stranger's Mac taught. Most of it is the app saying true things where it used to say hopeful ones.
A Mac that never turned sync on could still show "Syncing transcript" under a finished recording, for ever: the label was written after every transcription and only a sync pass could clear it. It no longer appears unless a pass is actually coming, and turning sync off takes the sync labels with it.
When sync genuinely fails, the reason now travels as far as the stall does. "Retrying sync" carries a plain sentence (your iCloud storage is full, sign in to iCloud, no connection right now) instead of CloudKit's phrasing, on the row, on the recording page and in Settings. listen sync status now also prints which CloudKit environment the build reaches and what the last pass actually said, so a stuck install can be diagnosed from one command instead of a screen share.
A brief iCloud throttle is no longer an alarm. CloudKit answers a burst with a sub-second "slow down", and that used to surface as "Sync needs attention" on the phone. The pass now waits out the server's own retry-after and goes again quietly. Passes are also cheaper: an unchanged device record republishes hourly instead of every two minutes, and an audio offer trusts its recorded transfer for fifteen minutes instead of asking the container every pass.
A first sync fills the library as rows arrive, instead of holding a spinner until the last transcript has landed.
Ask has always answered with an AI you bring, and the app only ever stated facts about what it found: accurate, and no help at all on a Mac with no coding tools. There is now a setup sheet, reachable from the composer's setup card and from Settings, laying out the four ways in with what each one costs, stated on the card rather than in a tooltip: OpenRouter (paste one key, what the iPhone app uses; the meetings you ask about leave the Mac under zero data retention), Claude Code or Codex (the subscription you already have, one terminal sign-in), the Claude app (ask there instead of here), or a model running on this Mac through Ollama (nothing leaves the machine, a few gigabytes of download). Setup ends by asking the model a real question, so it finishes on an answer rather than on "saved".
The surfaces around it stopped lying. A CLI that is installed but never signed in is described that way ("Installed. Run claude auth login…") instead of with an install command, which read as "not installed" to anybody not parsing the row like a developer; the Claude desktop app installs that CLI, so this is the normal state on a Mac that never chose one. An unknown sign-in state is re-checked in the background instead of being trusted until quit, and a question that fails on credentials now puts the sign-in card up instead of offering to fail the same way twice.
Settings, Developers can now write Listen into the Claude app's connector configuration itself: it backs the file up first, touches only Listen's own entry, keeps every other server and setting, and refuses a file it cannot parse rather than replacing it. The same action exists as listen mcp connect-desktop. The Claude app reads that file at launch, so the pane says to restart it and offers to do that too. What Claude can reach is unchanged: the same tools, the same limits, notes and tags the only writes.
Setup can no longer be dismissed mid-flow. Every step still has its own way past (Skip, Not now, Later, and a model download continues in the background), so nothing blocks; the close button's only real power was vanishing the wizard half-way and letting the library open with no model chosen. Running setup again from Settings keeps its close button.
Launching Listen from the installer image now says so. Dragging the icon to Applications and then double-clicking the one still in the DMG window runs the read-only copy, where updates cannot land and the login item breaks on eject. Listen now notices, offers the Applications copy (or puts one there), and never blocks if you decline.
Questions sent through OpenRouter now require Zero Data Retention, explicitly deny provider data collection and disable provider plug-ins. Listen still sends only the locally selected excerpts needed to answer a question: the library and its encryption key never leave the device, and Listen runs no relay server for the conversation.
The request path now records content-free timing, routing and outcome buckets, so a slow model, a failed request and a citation-repair loop can be told apart without recording the question, answer, transcript, people, titles or file names. This also gives the app enough evidence to choose a faster route instead of hiding a long wait behind one generic activity message.
Listen now reports anonymous feature counts, coarse duration buckets and crashes by default, with no question asked: a one-time migration turns it on for every install, including one that had earlier said no, and Share anonymous usage statistics in Settings, Privacy is the one place left to turn it off. Turning it off deletes anything queued and the install identity with it.
The schema is deliberately content-free: no recordings, transcripts, notes, questions, answers, titles, people, file paths, model output or stable library identifier. Development builds never send telemetry either; only an app made by the release pipeline can pass that gate. TELEMETRY.md documents every event and property, and the Privacy and Security pages now describe the same contract the shipped app enforces.
A tag was the one way to say what a meeting was about, and it stopped at the meeting. Asked to file the calls and the write-ups of them under one name, the app could do exactly half of it and had no way to say so, so it tagged the recordings and went quiet about the notes.
Recordings and notes share one set of tag names. listen tags lists each name once with both counts, either of which can be zero, so a tag only notes carry still exists. Adding one adopts the spelling already in the library, in both directions: tagging a note Kinsight where a recording holds kinsight files it under the one that is there.
Nothing is inherited. Tagging a meeting does not tag the notes about it, so filing a subject means doing both. That keeps two questions apart that are worth asking separately: what was said in meetings filed under this, and what has been written up about it.
The note page and the notes drawer inside a recording both have the tag strip the transcript header has, tag: in the search field narrows notes as well as meetings, and listen tags add --note <slug> does it from the command line. An agent can tag a note over MCP, including your own note: its words still cannot be changed from there, because they were not derived from anything and there is no way to get them back, but filing is one click to undo.
A note about exactly one meeting was left out of the Notes collection. Notes about several were listed, and so were notes about none, which is a rule that makes sense for the unfiltered library, where a meeting and the note about that one meeting would otherwise be two rows saying the same thing. The Notes collection contains no meetings for it to double up with.
Measured on a real library: it showed five notes of fourteen. If your Notes tab has looked emptier than it should, this is why. A tag filter had the same fault for the same reason.
A recording deleted on another device's say-so has always gone to the trash for a fortnight. A note did too, down one of the two paths that apply such a deletion; down the other it was removed outright, with nothing to put back. The trash even told you to put one back into recordings/ or notes/, which only one of the two paths ever made true.
Found on a real library, which lost four notes to it. Both paths now trash.
listen sync refetchA sync pass asks for what has changed since the last one, so a record that has not changed is never mentioned again. That makes anything lost on one device while its record survives in iCloud permanently invisible to that device, however many times it syncs. Restoring the file on a second Mac does not help either: the restored copy matches the record, so there is nothing to send.
listen sync refetch drops the change token, so the next pass asks the container for everything. It can only add: a token dropped on purpose is not the same as one the server could not resume, and the store reports no deletions for it, so the pass has nothing it could remove. Only the token goes, so this is not a re-upload of the library.
If notes or recordings have gone missing on one device and you can see them in listen sync inspect, this is the command. It does not resurrect anything the container no longer holds, and a backup is still the only route back from that.
Listen decides which tools a question may call, and until now told only one of the three ways of asking. Through Codex the agent saw the whole tool surface whatever you had said about writing, and through an OpenAI-compatible endpoint the restriction shaped what was offered and not what was accepted, so a model that named a tool it had never been offered was handed it.
The list now travels into the server itself, which is the only place all three have in common, and a tool outside it is refused by name. listen mcp --tools does the same for any client, and listen mcp on its own is unchanged.
The dictionary matches a term by how it sounds, and a name with "ight", "ough" or "eigh" in it could not be matched by sound at all. The silent letters left a digit behind in the phonetic code, so Kinsight coded differently from every mishearing of it and the one mechanism built for a product name skipped that name. Shown rather than argued, because nobody can predict a consonant code by reading their own rule: spelled Kinsite in a scratch library, kinside, kinzite, kinsyte and Kingside were all corrected, and spelled Kinsight none of them were.
A one-word term also only ever matched one spoken word, which is the other half of it, because a compound name is exactly what speech recognition splits: "kin site" and "can site" arrived as two words and nothing in the list could reach them. A one-word term now also matches across a gap of up to three words.
A 37-minute call separated into a third speaker holding 2.6 seconds of audio: "Yeah.", "Yeah." and "What were you saying?". That is not a person, and it cost three things at once. It put a chip on the meeting, it held the recording in "needs labelling" for ever because nobody was ever going to name it, and it withheld the automatic title from the two people who had done the talking.
A cluster under 5 seconds and under 1% of its track is now folded into the voice it most resembles, before the letters are handed out. Both cuts are required and both sit in measured gaps: on the development library the crumbs and the real people separate at 2.6 to 6.7 seconds and at 0.10% to 0.77%.
Speak's dictation is part of Listen and that app is not worked on any more, so a pane naming it made a reader stop and ask what it was. The Dictionary pane's "Imported from Speak" section, the Models pane's "shared with Speak", and the --from-speak flag have all gone.
Importing that file still works and always will: listen dictionary import ~/Library/Application\ Support/speak/dictionary.json does exactly what the flag did. The reader is deliberately liberal about the shape, because losing a convenience flag is cheap and losing years of somebody's corrections is not.
"Install updates automatically" was ticked, the gear carried its dot, and no version ever arrived. Listen put that badge up early by probing for update information on every launch, and in Sparkle 2.9.5 a probe breaks the automatic install three separate ways, each sufficient on its own: it marks a session in progress before the update cycle starts, so the only launch path that runs an overdue check is skipped; it stamps the last-check time before doing any work; and it schedules the next check a full interval after launch rather than when it was actually due. A probe downloads nothing, so a copy launched more often than every six hours installed nothing, ever.
Measured on the same seeded preference: build 242 moved the last-check stamp on a launch two seconds after a check, and build 243 left it alone. Nothing is called at launch now, and Sparkle's own cycle runs a real background check when one is overdue.
This cannot fix itself backwards. The copy you are reading this in is the one with the bug, so if you have been on 0.19.0 or earlier wondering why updates never landed, this is the last one you install by hand.
Install on quit is also a promise an app you never quit can never keep, and Listen opens at login and sits watching for meetings. The Updates pane has an Install and Relaunch button now. It refuses while a recording or a transcription is running, and says which, because a relaunch throws away an hour of meeting that has not been written out yet.
Sharing a transcript meant Export, which is a save panel and a file on disk, so sending one to a colleague meant writing a file and then going to find it again. Share and Copy as Markdown now sit beside it in the ellipsis, the sidebar's right-click menu and the File menu. Export stays: it is the one that asks where, and a share sheet cannot answer that.
What gets shared is the whole page, notes above the transcript, because that is the order it was read in and the summary is the half a reader of somebody else's meeting wants first. A note shares on its own. Neither is offered mid-recording, for the same reason every other verb is withheld there.
Copy as Markdown is Shift-Cmd-C rather than Cmd-C, because Edit's Copy belongs to the responder chain and has to keep working in the title and search fields.
There were two copies of this markdown before there was a third, and they had already drifted in what they put on the second line. The window, the share sheet and listen export --format md all go through one renderer now. The CLI's output is byte-identical to what it printed before, because scripts have been diffing it for months.
Recordings, People and Notes were three segments above the search field, so search meant a different thing in each of three states, the set could not say "all three", and an empty Notes tab read as the control being broken rather than as an empty answer. They are one list now, narrowed by a lens that behaves like every other pill in the row: a state with an off switch, whose absence is the whole library.
kind: and is: join tag: in the search field. A finished operator lifts out of the field into a pill, and backspace at the head of an empty field puts it back as text. The section headings are controls, so clicking one narrows to it, and the magnifier's menu names the operator each item writes. kind:people lists the whole roster, on Cmd-Shift-P.
The "5 recordings need a speaker" row is gone with it. It was the only one of these that asked unprompted, and its count can never reach zero, because some voices are never going to be named. The number moved into the magnifier, where it reads "Needs a speaker (5)" and you only meet it by going to look.
A two-person phone memo came back as a single cluster, which the microphone pass labels Me by design, so a meeting filed itself under one name with nothing on screen saying so. The 0.6 clustering threshold was measured against system tracks, where every voice arrives down its own call with its own microphone. Two people at a table share one microphone, one distance and one room's reverberation, so their embeddings land far closer together and the dendrogram merges them.
Measured across the library, counting speakers found by free clustering: a phone memo needs 0.65 to 0.85 and gives one cluster at 0.6, while an 89-minute webinar's system track is right at 0.6 and over-splits at 0.75. The two bands barely overlap, so a room gets its own threshold rather than everything getting a raised one. A 2-hour workshop in a room is the row worth reading twice, since 4 to 6 clusters looks like an over-split and is not: at 0.6 its largest cluster held 73% of the session, and at 0.7 that one voice became two speakers of about 30% each. Guarded by a 48-minute memo that genuinely holds one person and stays one cluster to 0.8.
A room that still separates into one voice says so in the log before it labels the whole recording, because on screen that failure looks exactly like an ordinary solo memo.
The phone writes Memo, 26 August, 12:20 when nobody types a title, and Listen read a title with no recorded source as one a person had chosen, so it never wrote over it. Naming the last speaker rewrote the transcript and left the title alone, and the calendar could never reach one either. Six of the eight phone recordings in the library were frozen that way, three of them still waiting to be labelled. The phone stamps the source now, and Listen reconstructs it for memos made by builds that did not.
Until now the only place release notes ever appeared was the pane Sparkle draws in front of an update, and that pane is dismissed and gone once you have acted on it. With automatic updates on by default, the ordinary path is a version landing on the next quit with its notes never having been on screen at all. A Release Notes window shows them now, reachable from Help, from the version number in About, and from Settings, Updates. It runs back through every past release and stops at whichever build you are running; listen changelog reads the same file from the terminal.
A speaker corrected on one device could be silently reverted by a sync pull from another, with metadata.json's own timestamp giving no sign anything had happened: the pull runs before the push that would tell the container about the edit, so a pull landing in between sees the container's old value against a local one that has already changed, and two values alone cannot tell "behind" from "edited but not yet sent". Recording sidecars are tracked per file now, the way the rest of sync already tracks conflicts, so an edit in flight survives a pull that runs while it is still on its way out.
Correcting a name from the transcript offered two similarly worded menu items, one renaming every turn a speaker has and the other moving a single paragraph, with nothing on either saying which was which; reported as confusing, and then reported again as a name that had vanished by the time its author looked back at the transcript. There is one item now: it opens with a checkbox that states the size of the edit in its own words, "All 63 turns by Nick change" or "Only this turn changes. Nick keeps the other 62", ticked by default.
Building that surfaced a real bug behind the second report. Moving a single paragraph to a new name could silently move whichever paragraph followed it too, because two turns from the same speaker can start at the exact instant the other track's interruption between them ends, and a window matched only on where a turn starts cannot tell them apart. Measured on a 1h29m call, correcting one paragraph silently moved the paragraph right after it as well. Fixed together with a second issue that made any speaker correction jump the transcript back to the top of the meeting, however far into it you were reading.
The transcript's sentence-edit menu acted on whichever sentence was under the pointer even when several were selected, leaving the rest labelled wrong; it now acts on the whole selection, states the count, and can delete a sentence outright, which a line one track picked up twice with an overlapping timestamp needed. Selecting text to open that menu no longer starts playback and scrolls the transcript out from under you, which used to happen because selecting begins with a click and a click on a paragraph normally seeks and plays. A room recording with a silent system track showed no transcribing progress at all, stuck at zero for the whole job because the percentage was reading from a track with nothing on it. An 89-minute webinar's system track was once clustered down to a single far-end voice, because a call with a microphone track had already run earlier in the same app session and the tuned diarizer meant for the mic track was left in the slot the system track's own pass reads from. The sidebar's transcribing row could wrap onto a second line and push its activity bar past the card's edge; it stays on one line now, giving up the clock and length for the stage description while a job is running.
Four separate settings decided how far behind a copy of Listen could fall, and each of them was its own way to sit on an old version. The scheduled check ran every two days, and 0.17.0, 0.18.0 and 0.18.1 all shipped inside a single day, so two days was not a floor anybody would have chosen. It is six hours now, and Listen asks the feed quietly at every launch as well, because Sparkle's own scheduler will not look again until its interval has run out however often you open the app.
Declining Sparkle's question the first time it appeared used to turn checking off for good, with nothing on screen saying so. Whether automatic checks are on is answered in the build now, so a copy cannot end up silently never looking again.
An update that has been found installs the next time you quit, instead of waiting behind a dialog for you to agree to it. That is a default rather than a rule, and the Updates pane has a checkbox that turns it off.
The gear in the library's title bar carries a dot once there is a new version, so the answer is where you already are rather than two panes into Settings.
The button along the foot of a person's card said Show Recordings, and it narrowed the library behind the card rather than doing anything with the person whose card was open. Their page, which is where everything Listen knows about them lives, was two levels down behind the ellipsis.
The button is Open in People now, and it goes there. Narrowing the library is still on the speaker chip's own menu, as Show Only followed by the name, which is where somebody who wants the list narrowed is already asking for it.
Turning sync on set a flag and nothing else: no production path ever created the key, so a fresh install reported "No sync key yet" on every pass while its iPhone waited for a key that did not exist. Macs already running Listen never saw this, because they inherited a key from the older file.
There is now one place a key is made. The first Mac creates it, and a Mac that can see another device in the container waits for iCloud Keychain instead of minting a rival key, which would have split a library in two silently. The Sync pane leads with the switch, says one thing per state, and shows a button only when it can act; it also gains the typed-key fallback for a Mac where iCloud Keychain never delivers. Setup asks about sync as its own step, so a new Mac holds the key before an iPhone ever asks for it.
"About Listen" opened a page inside the library window, behind the settings sidebar. It opens a window now: the icon, the version and build, and buttons for the website, the documentation and the source. It also carries a share sheet, a Copy Link button and a request to star the repository.
The website was missing rather than merely hard to reach. Until now the app linked the author's site and the source repository and never Listen's own page, so somebody trying to pass Listen on to a friend had nothing to send. That is exactly how it was reported.
Listen also had no Help menu at all, which is the first place a Mac user looks for a website. There is one now, holding the documentation, the website, the source, a way to report an issue and Share Listen. Cmd-W closes a window, which nothing in the app did before.
The settings section that used to be About keeps the version check and Run setup again, is called Updates, and sits with the other app settings rather than under Advanced. A button under the section list opens the About window, so the menu bar is not the only way to it.
The documentation button opens the README on GitHub. That is where Listen's documentation actually is today, and the button will point at a documentation site when there is one.
The author's personal site is a credit line rather than a link, now that Listen has a page of its own for the app to point at.
Speak, the dictation app Listen grew out of, is no longer recommended anywhere in the app: its dictation is part of Listen, so every route out to it offered a download for something this app already does. Importing a dictionary from Speak still works, and that section now appears only on a Mac that actually has the file, which is the migration it always was.
One of those was not cosmetic. Requests to a hosted Ask provider carried Speak's address in their attribution header, so Listen's traffic was credited to a different app on OpenRouter's dashboards.
An iPhone recording now reports when its audio is syncing, how far it has travelled and which Mac is transcribing it. The Mac keeps its full waveform while the compact iPhone row uses a percentage, and both replace vague idle states with the work that is actually happening.
The same path now completes rather than only looking active. A new recording is offered to iCloud, received by a Mac, transcribed there and returned to the iPhone without a restart or a second recording to wake it up. A missing CloudKit record was being reported as a batch failure and treated like an outage, which left the audio safe on the phone but prevented the first record from being created. Listen now distinguishes that normal first-sync case from a real connection failure.
If a retry is necessary, one rotating sync icon sits beside the explanation instead of a static retry icon and a second unrelated spinner. The recording continues to say that its audio is safe while no Mac has accepted it.
The MLX buffer pool is capped and released after a track finishes. This keeps one completed transcription from reserving accelerator memory that the next recording or another application needs. The model remains cached, so the next transcription does not pay the full model-loading cost again.
Until now, only the Mac that recorded a meeting had its audio; every other device had the transcript and nothing to play or re-transcribe. Listen can now publish a lossless copy, mic and system audio kept apart in one stereo FLAC file, so any device can play a recording or run it through the pipeline again. Settings, Devices has a Keep audio switch and a roster of what each device keeps and holds, so the choice to free local space is visible rather than silent.
Measured on a 1.07 hour meeting: 494 MB of raw tracks becomes a 61 MB master in 3.8 seconds, about an eighth of the size, with the two channels intact so speaker separation still works on a re-transcribe. A device only frees its own copy once another live device that is keeping audio reports actually holding it, never on the strength of the network alone.
A recording being worked on now names the Mac doing it and when it started, so two devices never race to transcribe the same recording, and a finished one carries "transcribed on \<device\> in \<time\>" once the library has more than one device in it. listen transcribe <id> takes the same lease as the background queue, so running it by hand no longer opens a second way in.
A recording waiting on audio from another device could sit that way for hours with nothing on screen to explain it. listen sync inspect --recording <id> now shows who holds the audio, whether a transfer is in flight, and what the manifest actually names, across every zone. A claim on a recording that goes nowhere expires after six hours rather than parking it forever, and only the device holding the audio writes that recording's metadata, so a stalled recording can no longer be handed back to itself with its progress erased.
docs/hipaa.html, docs/privacy.html and docs/security.html document what Listen sends where, what a security questionnaire will ask, and where it maps onto HIPAA and GDPR obligations, for anyone deploying it in a regulated setting. An organisation can now force Listen's settings through a standard MDM configuration profile: iCloud sync off, Ask restricted to a local model only, dictation history off, or backups redirected or disabled, each with a sample .mobileconfig and verify_compliance.sh to check it took. The activity log (listen activity) now records every tool call by name and id only, never by content, and that claim is asserted rather than assumed. Forgetting a person now leaves a tombstone, so a stale Mac pushing its old voiceprints back can no longer bring a forgotten speaker back to life.
A memo can reach the Mac, finish transcribing there and still leave the iPhone saying it is waiting. Two different races caused that. A sync requested while another pass was running could be forgotten, and a later phone pass could put its original metadata-only copy back after the Mac had published the finished transcript. Requests are now remembered, and a phone can add missing content without replacing the transcript, turns or details already published by a Mac.
The affected recordings are checked again once after updating. Measured on the live 11:13 memo that exposed the problem, the transcript reached the physical iPhone and remained byte-identical after a second forced phone sync. The audio transfer zone was empty afterwards.
Listen now carries a small copy of the source application's icon with each recording, sealed inside the same private iCloud payload as its other display files. Rows on the Mac and iPhone can show Chrome, WhatsApp, QuickTime and other source applications instead of a generic window.
Older recordings are filled in when a Mac that still has the source application installed syncs them. If no syncing Mac can resolve an application, the row keeps the generic fallback rather than inventing one.
A copy of your library is made once a day and kept for a week, and anything a sync deletes is kept for a fortnight, so a mistake is not final. The copies share their contents with the library, so they take almost no extra space. Settings, Storage says when the last one was made and where they are.
They live on this Mac, so they protect you from mistakes rather than from the disk itself failing. Time Machine is still the answer to that.
Everything Listen keeps in iCloud is sealed with a key only your devices have. Settings, Sync can now show it, so you can keep a copy in a password manager and still open what iCloud holds if you ever lose every device.
A recording or note removed by a sync from another device is now kept in your library for fourteen days before it is really gone. Whatever removed it, the files are still there afterwards. listen sync trash lists what is being held and where, and putting something back is a matter of moving the folder into recordings/ or notes/.
Listen also refuses to tell iCloud that everything has gone. A library that is suddenly empty is far more likely to be a disk that did not mount, a folder moved by hand, or a restore in progress than a decision to delete every recording at once, so it says so and changes nothing.
Renaming a speaker or correcting a sentence rewrites the transcript rather than the recording's details, and only the details were being watched, so those edits waited for the next scheduled sync instead of going immediately. Listen now notices any change to the library, whatever made it, including edits from the command line and from the MCP server.
One recording in the library had never reached iCloud at all: the copy of a transcript kept from before your first correction is stored under a name derived from the recording, and iCloud refuses names it has not seen before. Every edit to that recording was refused along with it. Those backups now sync, and their presence is what stops transcribing again from discarding your corrections without asking.
Listen now keeps transcripts, notes, people, tags and its custom dictionary in step through your private iCloud database. A meeting recorded on either Mac can appear on the other Mac and the iPhone without both devices being awake or on the same network. The existing wifi path remains available during the migration and is still running until the final cutover is tested.
The contents are sealed before upload with a key held by your devices. Record names, zone names and record types are opaque too, so titles and meeting times are not left outside the sealed content. Audio recorded on a Mac stays on that Mac. Audio from the phone is a temporary transfer and the phone keeps its copy until a Mac has written the bytes to disk and named itself as their holder.
Measured on the live library, the Production container holds 147 records: 71 recordings, 14 notes, 2 library files, 57 voiceprints and 3 devices. The audio transfer zone is empty after completed ingests.
On cellular, the phone could spend minutes saying "Sending 71 of 71" before it asked iCloud for a transcript the Mac had already finished. A pass now fetches incremental changes first. It also remembers a local stamp for each recording, so unchanged files are no longer sealed and checked against the server on every pass, and phone audio that has already been handed to a Mac is not uploaded again when Keep audio on this iPhone is on.
Finished transcripts are sent a few seconds after the Mac writes them rather than waiting for the two-minute fallback poll. Push notifications wake both apps for changes, and pull to refresh on the phone uses iCloud whenever iCloud is the selected transport.
The Mac's Devices pane now shows live work such as "Fetching 15 of 71" and "Sending 6 of 12", followed by when the last pass ran, what it changed and the first error or note conflict. The same pane lists the devices on the iCloud account. A new Mac fetches before it sends, so opening an older library cannot overwrite newer recordings before it has learned what changed.
Hand-written markdown notes remain part of the library format. Notes with no frontmatter, and notes whose recordings use a YAML block sequence, now run through the same offline end-to-end suite as generated notes.
A recording or note you delete on one device now goes from the others as well. Until now a deletion was obeyed when iCloud reported one and never reported when you made one, so a meeting deleted here stayed in iCloud and on every other device. Deleted notes could also come back, because a device that still held its own copy put it back the next time it sent anything.
A recording whose files cannot be read is never mistaken for one you deleted, so a damaged file on one device costs nothing on the others.
It used to filter the transcript down to only their turns, which read as the app having mislaid the rest of the conversation. Clicking a name is a question, not a filter: the transcript now stays whole, and what changes is where the waveform and the popover's own Play button point. Play there still skips straight to that person, but the pane's play button always plays the meeting.
Turns overlap in real recordings, and the highlight used to pick whichever overlapping turn started earliest, which is usually the wrong one: measured on one call, 59 of 105 clicks lit up a different paragraph than the one playing. It is ranked differently now and gets all 105 right on the same transcript.
With the composer open, it used to stop well short of the bottom, a knob resting a third of the way up with nothing under it. Fixed layout math that was making room for the composer twice; the scrollbar now runs the full pane and sits flush against the window's edge.
Press fn + left shift anywhere on the Mac, say what you want written, press it again, and the words are typed into whatever you were using. Escape cancels, and so does the trash button on the floating pill. Everything is in Settings, Dictation: the shortcut, the engine, the sounds, the pill.
This is Speak folded in rather than rebuilt. Listen was built from Speak as a template, so by the time dictation moved the two already shared a microphone path, a speech model, a Hugging Face cache, a custom dictionary, a settings framework and a release pipeline. What dictation needed that meeting recording did not was a global shortcut and a way to type. That is the whole difference, and it was not worth a second app, a second menu bar icon, or a second 2.5 GB of weights held in memory.
It needs Accessibility, which is what lets Listen see the shortcut and type for you. Recording meetings never uses it, so anyone who only wants the recorder can ignore the whole feature and will not be asked for anything.
The custom dictionary now applies to dictations as well as meeting transcripts. A name Listen mishears in a meeting is the same name it mishears when you dictate, so one rule fixes both. Both halves of a term are live again: the phonetic match, which needs no model and works on any macOS, and the spelling hint that stops the polishing model rewriting a word it does not know.
On macOS 26 with Apple Intelligence, dictations can go through a copy-editing pass before they reach the clipboard: punctuation and capitalisation added, um and uh removed, paragraphs where the topic turns. Off by default, because it costs about a second and rewrites your words.
It is a copy editor and never an assistant, which took some doing. Told it was an assistant, the model answered the text: "what time is the meeting tomorrow" came back as "The meeting tomorrow is at 3 PM", inventing the time. A dictated question now comes back as a question, a sentence you cut off stays cut off, and a reply that collapses or grows past what editing can explain is thrown away in favour of what you actually said.
There is a second pass for false starts, where you begin a phrase, break off and say it again. It runs only on sentences that look like that, which measured over a real 260-dictation history is about one dictation in ten, so the other nine pay nothing for it.
Works, and your dictation is also on the meeting's microphone track, because it is your voice in the room. Listen does not open a second microphone to do it: the recording already holds the device, and a second claim on it would renegotiate the Bluetooth profile the meeting is being recorded through.
One speech model serves both now instead of one each, which is the difference between fitting and not fitting on an 8 GB Mac. A dictation asked for while an hour-long recording is being transcribed no longer waits for the hour.
The speech model carries over on its own: both apps always used the same download, so there is nothing to fetch again. The configuration does not. Set the shortcut again in Settings, Dictation, and bring your Speak dictionary across in one press from Settings, Dictionary.
Questions about your recordings used to need Claude Code or Codex installed. Any OpenAI-compatible endpoint answers them now, which covers the case this app should be best at: a model running on the same Mac at http://localhost:11434/v1, with no account anywhere and nothing leaving the machine. Twelve are set up in a press each, among them Ollama, LM Studio, llama.cpp, OpenRouter, OpenAI, Groq, Mistral and xAI. Any other URL can be typed in, several can be configured at once, and the composer switches between them.
Which local model, measured on four questions with checkable answers against a five-recording library: qwen3.5:35b at 23 GB answered all four in 7 to 18 seconds, and the 81 GB model matched it at roughly three times the wall clock, so the larger download buys nothing on this task. gemma4 at 9.6 GB is faster again and got three of four.
An agent CLI brings its own tool loop, and a provider is one stateless request, so Listen runs the loop itself. Two consequences are worth knowing. A model that advertises tool support will still answer from nothing, so an answer with no tool call behind it and no earlier conversation to draw on is flagged rather than trusted. And keys live in the Keychain, never in preferences: an endpoint that is not on this machine says in words that your transcripts go to it, before you save it.
The model menu lists the ones you have used, with a searchable picker behind it, because a provider can offer 318 tool-capable models and the first twelve alphabetically are ones nobody chose.
Neither agent CLI reports a connection that has gone away, which was measured rather than assumed: against a blackholed API, claude -p ran 100 seconds with nothing on stderr and no exit, and codex exec did the same. The pane said "Thinking" until somebody pressed Stop. Listen now watches the network path and, once a run has been quiet for 20 seconds, opens a connection to the backend's own host, which is the only half that catches a router still handing out addresses over a dead uplink.
Asking with no connection is refused with the reason. Losing it under a running question turns the line amber and stops the sweeping highlight, which is there to say the process is alive. Nothing is ever killed for a network reading, and nothing retries by itself: a failed turn offers Try again, which replaces the attempt rather than adding to the conversation.
A question still starts in the composer at the bottom of whatever you are reading, and a conversation can now take the whole window: the frame goes, the text sits in a 620 point column, which is 105 characters of the body size, the page scrolls rather than a panel inside it, and the sidebar underneath becomes the list of conversations instead of going on listing recordings behind a view nobody can see. History belongs to the two screens that are about conversations, the home page and a conversation itself, and picking one out of it opens the page rather than a card over an unrelated meeting.
With it: a follow-up typed while an answer is streaming waits its turn instead of vanishing, and Stop hands it back to the composer; Delete is a verb on the conversation's own menu and asks nothing first, because a conversation is working-out and anything worth keeping was already saved as a note; and the meeting being recorded has no composer at all, since that screen's bottom edge is the meters that say whether your voice is arriving, and nothing is transcribed until Stop.
Saving an answer as a note records which conversation it was promoted out of, and the "Asked for" line on the meeting page opens that conversation again. Notes written before this release are matched on their question instead.
The ellipsis in the title bar is about what is on screen rather than always about a recording, so a note gets Open Conversation, Show in Finder and Delete, and a person gets the verbs that belong to them. The sidebar's right-click had the sharper half of the same bug, aiming a meeting's red Delete at a note.
An hour-long meeting spent that hour under a floating panel in one fixed corner, and putting the panel away was the only answer to it covering the thing the meeting is about. The whole face of it is a grab area now, buttons excepted. What is stored is a corner and two insets rather than a point, so the panel grows the right way as the clock reaches an hour and still lands on screen when it is read back on a different display.
listen dictate <file> runs the dictation pipeline over audio, listen polish [text|-] runs the text half, and listen dictations reads what you have said. The first two exist because dictation is otherwise only reachable by holding a key and talking, so a change to it could only be tested by hand.The sidebar's three-way picker is gone. The recordings list is the library: notes sit among the meetings in the same days, and typing a name brings back that person's card above the results as well as the transcripts they appear in. A note is a row only when it has no single page to live on, which means a synthesis of several meetings or a note about none; a note about exactly one recording lives on that recording, because listing it here too would put every meeting in the library twice.
Transcript and Notes have stopped being two tabs you choose between. They are one page now, what you wrote above and what was said below. The transcript keeps its own scroller, which is load-bearing: playback scrolls it to the sentence being spoken, and a shared scroller would drag the note off the top of the window every time somebody pressed play with a caret in it. The note takes the height of its own text between three lines and six, measured against the longest of the 11 notes in this library.
The question bar belongs to the window rather than to a meeting, so a question asked with nothing selected is a question about the library. That case had no way to be asked before, and it is the one a library-wide answer exists for.
Conversations moved out of the recording folder into chats/, naming the meetings they are about as a list. A question spanning four meetings had four bad homes and a question about none had nowhere to go. Existing conversations are moved on first launch, keeping their turns, their session and the time of the last thing said in them rather than the time the move ran.
The answer arrives in a drawer over the page instead of replacing it, in three sizes, and putting it away does not lose it. The composer always starts empty, at launch and on every meeting: it used to load the newest conversation for whatever you had arrived at, so opening the app put you inside an old conversation nobody had asked for. History, in the title bar, is how you go back, and it lists every conversation rather than the current page's. Delete is one item at the foot of that menu acting on the conversation that is open, because conversations are titled by their first question and a list of four rows with two identical pairs is a delete you cannot aim.
Answers named recordings and left them dead. Each claim now carries a small numbered reference; clicking it shows what is behind it, the recording with its date, length and speakers, or a note, or a person, and the card is what opens the page. Two clicks rather than one, deliberately: a citation is read in the middle of a sentence, and a number that swaps the page under you is one nobody presses twice.
The identity is the agent's, not a text match. It writes the recording's id after the claim, so a library where most recordings are called "New recording" cannot send you to the wrong meeting. A reference naming something the library does not have is dropped rather than drawn, and the markers never reach a note or a file on disk.
Measured against Claude Code, which cites unprompted once its brief asks for it. Codex writes the same answers through the same brief but its compliance has not been measured, so an answer from it may carry no numbers at all.
Listen ships no model and holds no key. A new Ask pane drives whichever of Claude Code or Codex is already installed and signed in on this Mac, handing it listen mcp as the only way to reach the library. So a question about a recording costs nothing beyond the subscription already paid for, and never leaves the machine by a route the agent does not already take.
Ask sits beside Transcript and Notes as a third mode: starter questions, the work shown as one line that is replaced rather than appended to as it runs, and Save as note to promote an answer into the library. listen ask is the same engine from a terminal, and is how it was measured. When neither CLI is installed or signed in, the pane now says which, instead of showing four dead starter chips.
The calendar can only name a meeting that was scheduled, and most calls are not: four recordings in this library sat at "Untitled" with the nearest calendar event 51 and 32 minutes away, nothing for it to find. A recording is now also named after whoever spoke, the moment the last unnamed speaker is given a name. It follows further renames and stops the moment somebody types a title of their own; a title typed while a recording is running now survives stopping it, where it used to be discarded on reload.
Recordings whose speakers were already named before this update need listen title backfill to pick it up; it is a dry run unless you pass --apply. An unnamed recording reads "New recording" rather than "Untitled" on screen, though the string stored on disk is unchanged.
An hour of a call was captured with the laptop lid shut: macOS had switched the built-in microphone off, and Listen followed the system default onto it anyway, filing 56,239,952 silent samples as a healthy one-speaker meeting with nothing on screen to say so. Recording now drives the chosen microphone directly instead of asking AVAudioEngine for the system default, moves off a device that has never been heard from mid-meeting, and a dedicated recording screen shows one lane per track instead of three empty tabs, so a track that never started is visible while it still matters. A finished recording that captured no voice says that on its row.
listen command can transcribe again. Running it from ~/.local/bin, which is what the Developers pane itself tells you to do, died with "Failed to load the default metallib" on every call that needed the model. It now re-execs the real binary inside the app bundle first.listen-sync serve on every install, because the sync agent carries the app's path as an argument, not as its own identity. That could strand a phone's sync mid-upload until the app was force quit.Reported as "for some reason I can't download it", and then "nope" to whether any error had appeared. That second answer was the accurate one: nothing appeared.
Pressing Download did start the fetch. About half a second later the button went back to reading "Download Parakeet v3 (2.51 GB)", because the setup pane repaints on a timer and put the old title back, so a download that was running looked like a press that had done nothing. Pressing again started a second fetch over the same directory. Two fetches clearing and repopulating one cache is how that Mac ended up being told Key decoder.prediction.embed.weight not found in ParakeetModel, which is what mlx-swift says when the weights it wants are not all there.
The step now has a progress bar and a line saying what it is doing, for the whole of the download rather than for the first moment of it. The model buttons are disabled while bytes are arriving, so switching cannot leave 2.5 GB coming for a model nobody wants any more.
Continue no longer trusts the size of a directory. It used to, which meant that after a failed attempt left something roughly the right size behind, pressing Try again walked straight past the model step to "You are set" holding a model that had just refused to load. Continue now loads the weights before moving on: a second or two from a warm cache, and the only check worth anything, because a directory of the right size still has to parse.
A copy short of the measured size is deleted before a retry rather than accepted. A copy that is the right size and still will not load is replaced, but only after it has failed once and only when you press the button again. Throwing away 2.5 GB is not something to do on a hunch.
If a broken copy is already on disk from before this release, transcribing now stops and says what is wrong and which button replaces it, instead of producing an empty transcript. MLX reads the missing part of a short file as zeros without complaining, so that failure had no other symptom.
Settings has a Devices pane. It shows a QR code carrying the pairing key and this Mac's address, so there is nothing to type on the phone, and under it the phones that have connected, each with when it was last seen. There is a "Copy the code instead" button for when pointing a camera at the screen is not convenient.
Whoever scans that code can read every transcript in this library. Treat it the way you would treat the screen it is on.
Removing a device stops this Mac answering it. It does not reach into the phone to delete what already synced, and the pane says so rather than leaving you to assume either way. "Forget every device and start again" rotates the key and clears the list with it, because a list of phones that survived a key change is a list of phones that cannot connect, which is worse than an empty one: it looks like they still can.
Listen does not do the sync itself, and this release does not ship the parts that do. A separate helper called listen-sync serves the library on your local network as a LaunchAgent, and it lives in another repository under another licence; the phone app is separate again. Until the helper is installed on this Mac there is nothing for a phone to pair with, and the pane explains that instead of showing an empty list that reads as a bug. What shipped here is the Mac's half of the pairing.
The library list re-reads every 3 seconds while the window is visible, and the Devices list every 2. Both used to be read when they were built and again when you came back to the app, which was enough when the only other writer was a second Mac syncing a folder in the background. A phone is different: you are holding it and watching this window at the same time, and a recording that arrived and transcribed a minute ago while the list sat still reads as a sync that did not work.
Only while the window is visible. A poll behind a closed window is work nobody asked for.
Until now Listen assumed every recording was a call: the microphone is you, the system track is everyone else. Put the laptop on the table in a meeting room and that assumption files four people under your name, with nothing on screen suggesting anything went wrong. Reported from a 47-minute workshop whose transcript read "speakers: Me".
Listen now works out which kind of recording it has, from the recording itself: nothing was on a call, and nothing sustained came out of the speakers, so nobody was remote, so the microphone is carrying the room. It then separates the people around the table the way it separates a call. That workshop re-transcribes as five voices across 180 turns instead of one.
One voice on the microphone is still just you, so a recording made alone at a desk is unchanged, and so is every call.
The one case it cannot decide is the meeting that is half in the room and half on a call, because a system track with speech in it looks the same either way. Right-click the recording and tick Recorded in the Room; it offers to transcribe again, which is when who said what is decided. listen transcribe <id> --room is the same thing from the terminal, and listen show prints which way a recording was read.
Your own voice was the one thing the voice bank could not recognise. Nothing ever clustered the microphone track, so Me was a label with no voiceprint behind it, while every other participant had one.
Calls now file one. A room recording is what needs it: the people around a table arrive as Speaker A and Speaker B, and a stored voiceprint is what lets Listen say which of them is you without asking. It takes one transcribed call to learn, so the first room meeting after updating will still ask. listen enroll <id> takes the print from a call you already have.
The panel that floats in the top right corner for the length of a meeting now carries a minus button after Stop. Pressing it hides the panel and does nothing else: the recording carries on, and the menu bar icon still says so.
That corner is also where a screen share tends to put the thing somebody is pointing at, and until now the only way to clear it was to stop recording.
It comes back two ways. The menu bar grows a "Show Recording Panel" row under Stop Recording while the panel is hidden, and the next recording starts with the panel visible again: hiding it applies to the meeting you are in, not to every meeting after it. That is deliberate. A recorder running with nothing on screen is only acceptable when somebody asked for it this time.
The one thing it will not hide is the question. When Listen has started recording because it detected a call and is asking whether you are in a meeting, the panel stays and the minus is not there, because that answer decides whether the recording is kept and the panel is the only place to give it.
Long recordings are transcribed in pieces, and every release until this one cut those pieces at a fixed number of seconds, which usually means cutting through the middle of a word. Listen now slides each boundary back up to ten seconds to the quietest 200 ms it can find, so a seam falls in a pause and the pieces need no overlap and no merging.
Measured against 0.5.0 on a track of 300 numbered sentences at the same piece length: 56 sentences missing and 50 transcribed twice, against nothing missing and nothing duplicated. The known limitation carried since 0.1.0, about six corrupted words an hour on a large Mac and about 33 on a small one, is what this removes.
It is also faster. Decode cost grows sharply with the length of a piece, so once a seam is free the reason to use a long one goes with it: every Mac now uses 120 second pieces, three at a time, which on a 3643 second recording is about twice as fast as the 600 second pieces it replaces.
The pane drew a spinner. It now draws the recording's own waveform in two lanes, everybody else above and you below, each filling as its pass decodes. The boundary is where the reading has got to, to the bar.
There is no time estimate anywhere, deliberately. A throughput figure measured on one machine is a promise another cannot keep, so it counts pieces done out of pieces to do and says nothing it cannot know.
Transcribe Again is a submenu now: Parakeet v2 or v3, per recording, recorded in the recording's own metadata rather than read from a setting that has since changed. Re-transcribing discards hand corrections, so it asks first, which it did not before.
Worth knowing before you re-run an old import: v3 handles more languages, v2 is English only, and an imported recording transcribed elsewhere may have been in neither.
A suggestion used to be scored against the single best recording of somebody's voice, which is only as good as that one recording. It is now scored against the average of all of them. Measured leave-one-out over this library: the same person scores +0.642 to +0.914 and different people up to +0.371, a wider gap than the numbers it replaces, which had scored a correct match at +0.603 because the one labelled recording of that voice was the least representative of five.
The percentage is gone. It was a similarity score times a hundred on a scale whose whole useful range is 0.37 to 0.91, so a correct match displayed as "60% match" and read as a coin flip. It says how sure it is in words instead, and names the runner-up only when the margin is genuinely narrow.
When a voice clears +0.75 and beats second place by +0.15, Listen names it without asking. At that cutoff 85% of true matches land and no wrong pair scores above it. Three things keep that safe: an automatic name is never used as evidence for the next one, so a mistake cannot spread; it is marked as automatic in the recording's metadata and in listen show; and listen voices prints the ranking, the margins and the thresholds, because a name applied without being asked has to leave something to argue with.
The picker asked "who is this" and offered only inference: how long they spoke, what the voice bank thinks, who was on the invitation. It now has a Play button. Two seconds of the voice settles what all of that is circling, and it plays through the pane's own player, so the playhead moves and the transcript scrolls to them.
Asking about somebody narrows the transcript to their turns, for exactly as long as the asking lasts: close the popover, by dismissing it or by naming them, and the whole meeting is back. The waveform greys everybody else at the same time, across the whole recording rather than only the part already played, which is how you find a quiet participant. This library holds a 97 minute call where one speaker talks for 0.0 minutes and another for 0.1, and both were on screen and invisible before this.
You can also answer "that is me" from the picker on an imported recording, which has no microphone track to merge yourself into and so had no way to say it.
A row above the sidebar list counts them, and is gone entirely when the count is zero. Clicking it shows those recordings; View > Recordings Needing a Speaker (⌘U) asks the same question when the row is not there to ask it from.
It is a count of what is actually in the transcripts rather than of what the metadata claims, and those disagree: over the 31 transcribed recordings here the stored state says 17 where the truth is 13, in both directions, because it is only written by the window and half this library was labelled by a pipeline that never touched it.
The gear sits at the top of the sidebar next to the control that collapses it, in all three collections, and the Settings row at the bottom of every list is gone: the lists run to the bottom edge now. Settings itself takes the same shape, its name where the app's name goes and the way back at the top right.
The sidebar could not be resized at all in Recordings, and could be in People and Notes. That was a constraint belonging to the transcription picture above, which is hidden almost all the time and was quietly holding the content pane at exactly 700 points and the window between 799 and 1168. Both drag freely now, between 298 and 468 points of sidebar.
Speaker labelling is per sentence rather than per word, so two people talking over each other inside one sentence come out as one speaker. Meeting detection is on by default: it starts recording, then asks on screen, and answering no deletes the audio straight away. Diarization runs on the system audio track only, because your own track is you by definition.
Reported from a real 49 minute call: the other speaker at 100% of talk time and the user at 1%, because a headset was turned on a few seconds in. When the microphone's format changes underneath it, AVAudioEngine stops calling its tap and never resumes, so the rest of the meeting recorded as silence with nothing logged anywhere.
The obvious fix does not work, which is the part worth knowing. With the device pinned the way Listen pins it, the configuration-change notification every guide points at fires once at startup and never at the hardware change, and the engine reports itself running for the whole outage. Listen now watches Core Audio's own property listeners, which do fire, and rebuilds the engine in about a third of a second. A watchdog on the symptom catches whatever they miss at two seconds.
Reproduced by changing the input device's sample rate 8 seconds into a 26 second recording: before, 8.6 seconds of microphone against 26.0 of system audio.
A recruiter screen, a hiring manager chat and a referral catch-up share no word, no attendee and no week, so free text, a person and a date range between them cannot name "the job hunt calls". A tag is how a question says what it is about.
Tags are free text on the recording, filterable in the window, at the command line and over MCP, and an agent may write one: it is somebody's filing of a meeting, the same side of the evidence line a note is on. Filters stack, so Maxime and Edgar together means both.
The New Recording row was at the top of the sidebar, so collapsing the sidebar took the app's primary action off the screen with it, leaving only Cmd-N and the menu bar. It is now a capsule floating over the bottom right of the content pane, present whatever the sidebar is doing, and it is the stop control too: start and stop are one toggle, and putting them in opposite corners means crossing the window to undo a press.
Running, it is on every screen. Settings, People and Notes have no row with a clock in them, so a meeting started an hour ago would otherwise have no visible end from any of them.
Listen has no account and no server, so there has never been anything to sync with. But the library is ordinary folders with no database anywhere, which makes it about the easiest thing there is to put behind Resilio Sync, Syncthing or a network share. SYNC.md is the guide.
Measured on a real 41-recording library: the audio is 8.3 GB and everything else is 6.5 MB, and nothing but playback reads the audio. So the audio stays on the Mac that recorded it and about 6.5 MB crosses, plus roughly 160 KB per new meeting. Both Macs can record, and each transcribes only its own meetings.
Three things had to change in the app for that to be true rather than nearly true. The transcription queue no longer picks up a recording whose audio is on another Mac, which is what stops two machines transcribing the same meeting and writing over each other's metadata. The player keeps its place and says where the audio is, instead of vanishing and leaving a gap that reads as playback being broken. And the window re-reads the library when you come back to the app, so a meeting recorded on the other Mac appears without relaunching, which also fixes a note or tag written by an agent not showing until something else happened to reload the list.
Known limitations, both of them consequences of what sync means rather than bugs. Deleting a recording anywhere deletes it everywhere, including the audio on the machine that has it. And preferences do not sync, only the library does, so a second Mac shows your own turns as Me until you run listen me "Your Name" there and starts with an empty meeting-detection skip list.
The README had grown to 557 lines with MCP the largest section in it, so that moved to MCP.md: how to connect each client, what every tool takes, and how to walk a large library without reading it whole. It gains per-client setup for Claude Code and Hermes.
Two things worth knowing if you wire up an agent. Hermes profiles do not inherit MCP servers, so a server added to the default profile is invisible from every other one with nothing reported. And point any client at the installed app or the listen symlink rather than a build directory: the config stores a path and an update replaces the app at that same path, so a new version is picked up with nothing to re-register.
Listen's menu now opens with its own name and mascot. That row is there because an icon in a menu bar of twenty is not a name, and the only other place the app said what it was called was About Listen, eight items down.
Under it, the five most recent recordings. Clicking one opens it: the library comes forward with that meeting selected and its transcript on screen, whether or not the window was open when you reached for the menu. Each row is stamped with the time if it was recorded today and with the date if it was not, so a meeting from Tuesday does not read as one from this morning. The recording in progress is deliberately not in that list, because it is already the two rows at the top of the same menu.
A row now appears when a permission is missing, next to the one that has always appeared when the speech model has not been downloaded. Both go straight to the settings pane that can do something about it. The elapsed clock is also correct now: it is read when you open the menu rather than when the recording started, so it no longer reads 0:00 for the length of a meeting.
Sparkle answers a check in a window that is then dismissed, taking the answer with it, and a scheduled check that finds nothing says nothing at all, so "am I on the latest version" had no answer that survived closing a dialog. About now carries Check Now, a Check automatically switch, the result of the last check and when it ran, alongside the app icon, the version and a line saying Listen is free software under the AGPL 3.0 with a link to its source.
Nothing about what is sent changed. The check asks whether a newer version exists and sends nothing about you, and every update is still verified against Listen's signing key before it is installed.
About six words an hour are corrupted at chunk seams on a Mac with the memory for 600 second chunks, and about 33 on a Mac with 12 GB or less, where the chunks are 120 seconds. Speaker labelling is per sentence rather than per word, so two people talking over each other inside one sentence come out as one speaker. Meeting detection is on by default: it starts recording, then asks on screen, and answering no deletes the audio straight away.
Every recording now has a Notes tab. It is one plain Markdown note that is yours: open it and type, during the meeting or afterwards. There is no new-note button and nothing is saved until there is something to save. If Listen asks whether a detected recording was a meeting and you say no, it asks again before discarding a note you made during it.
An agent connected over MCP can read that note but can never change it. It can write a separate Markdown note with the summary, decisions or open questions you asked for, and file it against one or several meetings. It cannot rename a speaker, alter a transcript or delete a recording. Agent-written notes can be edited safely: Listen refuses an edit when the note changed after the agent read it, rather than silently replacing somebody else's work.
Notes sit beside the recordings in the library, not inside one recording, so a write-up spanning several calls stays attached to every call it used. Removing a recording does not remove a note that also concerns other calls.
The sidebar now switches between Recordings, People and Notes. People groups meetings by who was there; Notes puts every write-up in one place. Search stays inside the collection you are looking at. Settings also has a name for your own track, shown in the app while the stored recording label remains safely Me.
Selected recordings, tabs and controls now use Listen's website blue rather than the generic macOS blue. It is sampled from the app icon and retains dark text for contrast.
About six words an hour are corrupted at chunk seams on a Mac with the memory for 600 second chunks, and about 33 on a Mac with 12 GB or less, where the chunks are 120 seconds. Speaker labelling is per sentence rather than per word, so two people talking over each other inside one sentence come out as one speaker. Meeting detection is on by default: it starts recording, then asks on screen, and answering no deletes the audio straight away.
One change, and it is a default rather than a feature.
Meeting detection only runs while Listen is running. The checkbox for opening it at login has been in Settings since 0.1.0, sitting unchecked, which meant anybody who did not go looking for it had a recorder that quietly missed every call and offered no account of why. That is the same silent failure that made detection itself default to on, so the two defaults now agree.
New installations only. Upgrading from 0.1.0 or 0.1.1 changes nothing on a Mac that is already set up, so if you want it there, the checkbox is in Settings, General, under Startup. Turning it off is equally final: the decision is recorded the first time it is considered, and no later launch overrides what you chose, here or in System Settings, General, Login Items.
The cost, plainly. Listen keeps a Dock icon and a window rather than living only in the menu bar, so opening at login means the library window opens with it. Suppressing that needs a way to tell a login launch from an ordinary one, and the obvious candidate is not one: NSApplicationLaunchIsDefaultLaunchKey never mentions login items and is also false for window restoration, so trusting it would trade an unwanted window for the worse failure of opening Listen and seeing nothing at all.
About six words an hour are corrupted at chunk seams on a Mac with the memory for 600 second chunks, and about 33 on a Mac with 12 GB or less, where the chunks are 120 seconds. Speaker labelling is per sentence rather than per word, so two people talking over each other inside one sentence come out as one speaker. Meeting detection is on by default: it starts recording, then asks on screen, and answering no deletes the audio straight away.
A fix for Macs with less memory, and the first update that arrives with its own notes attached.
It used to work in 600 second chunks on every machine. That figure was measured on a 128 GB Mac with nothing else running, where the pass peaks at 3.28 GB. On an 8 GB M1 Air, alongside a browser and the video call the meeting is in, the same pass can exhaust Metal memory and take the transcript with it. That lands an hour in, after the recording, where it costs the meeting rather than a retry.
On Macs with 12 GB or less, chunks are now 120 seconds, which is the figure Speak has shipped on 8 GB machines throughout. The cost is real and worth saying plainly: one word is corrupted at every chunk seam, so an hour-long meeting on a smaller Mac now carries about 33 corrupted words instead of about 6. That is worth paying when the alternative is no transcript at all.
Nothing changes on a Mac with the memory to spare.
Because two Macs can now disagree about the same file, listen transcribe reports the chunk length and the seam count on every run. Without it, "my transcript has more glitches than yours" has nothing behind it to check.
The update pane was blank in 0.1.0, so the only thing it gave you to decide on was a version number. It carries these notes from now on.
Homebrew 6.0 refuses to load a cask from a tap that is not one of its own until you say so:
brew trust --cask mugoosse/tap/listen
brew install --cask mugoosse/tap/listen
About six words an hour are corrupted at chunk seams on a Mac with the memory for 600 second chunks, and about 33 on a smaller one. Speaker labelling is per sentence rather than per word, so two people talking over each other inside one sentence come out as one speaker. Meeting detection is on by default: it starts recording, then asks on screen, and answering no deletes the audio straight away.
First release. Listen records a meeting from both sides, transcribes it, and works out who said what. Everything runs on your Mac and nothing is uploaded.
listen transcribe some.wav needs no permissions at all, which makes it the quickest way to tell a model problem from a capture problem.
Reports and confusion are both useful: https://listenbrain.app/support