Building · In progress

pebbl.

A meeting notetaker that shows its receipts

pebbl. is a small macOS app I designed and built with Claude in a day. It records, transcribes on your Mac, and links every decision and promise back to the second it was said.

Role
Product, design and build, with Claude
Timeline
October 2026, first build in a day
Platform
macOS 13+, menu bar first
Stack
Tauri 2, Rust, React, Whisper, Claude
1 day
from written spec to a decision graph
200
automated tests, 97 Rust and 103 frontend
33
design decisions written down as they were made
0
audio files leave your Mac

pebbl. lives in the menu bar. It records your microphone and, on newer Macs, the call audio as a separate track. It turns speech into text on your Mac, then writes notes where every decision and action links to the exact moment it was said.

A meeting in pebbl., in light and dark mode
Notes, chapters, promises and decisions, with the transcript alongside. All screenshots use sample data.

The problem

Notetakers fail quietly, in three ways. They look like they're recording when they aren't, and you find out afterwards. They write confident summaries you can't check, so one wrong action poisons the rest. And they overwrite last week's decision with this week's, as if it never happened. Many also join your call as a bot, which changes the room before anyone has spoken.

A typical notetaker

  • A bot joins the call
  • A summary you can't check
  • Actions assigned to “the team”
  • Yesterday's decision overwritten
  • Audio uploaded by default

pebbl.

  • Starts quietly from the menu bar
  • Every claim links to the second it was said
  • My promises, from your own mic
  • Both versions kept, and linked
  • Audio never leaves the Mac

The journey

I mapped one meeting and the week after it against the five jobs in the spec: capture, understand, remember, verify and act. The meeting itself isn't where it hurts. The pain sits afterwards, when you need to trust, find or act on what was said. So that's where pebbl. spends its effort.

Journey map · one meeting, and the week after

The pain isn't the meeting. It's the moments after, when you need to trust, find or act on what was said.

StartingCAPTURE
Joins the call. Wonders whether to record.
A bot joins as a participant. Everyone sees “AI notetaker” and the room goes formal.
DuringCAPTURE
Talks, half-types notes just in case.
Can't tell if audio is really coming in, so keeps typing as a backup.
Wrapping upACT
Agrees next steps. Says “I'll send it Friday”.
The promise is buried in a paragraph of summary, assigned to “the team”.
Right afterVERIFY
Reads the notes, forwards them.
It sounds right but can't be checked. One wrong action and they stop trusting all of it.
Days laterREMEMBER
Gets asked “what did we decide?”.
Scrolls old summaries, then rewatches a recording to find one sentence.
Next meetingUNDERSTAND
The plan changes.
The old answer is silently overwritten. Someone asks who said what.
CONFIDENTANXIOUS
Typical notetakerPick a stageMapped from the five jobs in the spec: capture, understand, remember, verify, act.

Five principles

  • Small. No clutter, no performative complexity.
  • Dependable. Accurate state, resilient capture, recoverable data.
  • Quiet. Useful when needed, invisible when not.
  • Grounded. Show the evidence, never invent certainty.
  • Actionable. Turn remembered conversations into work.

Each one settled real arguments later. Grounded is why a paraphrase can't become a quote. Dependable is why the word Recording waits for real audio. Quiet is why nothing joins your call.

1. Evidence Mode

What: every decision, action and chapter carries a citation: a transcript line and the words quoted from it. Click it and you hear that moment. Why: a summary you can't check is a rumour. The fastest way to lose someone is one confident, wrong action item.

Evidence Mode · every claim needs a receipt

A model will happily cite a line that doesn't say what it claims. So pebbl. checks every citation before you see it.

Notes

Transcript

  1. 0:07OthersMorning. So the main thing today is the booking cards and whether we show availability up front.
  2. 0:15YouRight. From the research sessions, people kept opening every card just to see the next free slot.
  3. 0:25OthersThat matches what support is hearing. Let's show availability dates upfront on the card itself.
  4. 0:34OthersCan we ship that in October, or is that too tight?
  5. 0:41YouOctober works if we keep it to web first. I'll send the revised booking cards by Friday.
  6. 0:50OthersGreat. Can you check whether the API returns the next slot already?
  7. 0:57OthersYep, I'll look into it today.
Pick a note on the left to find where it came from.

The important call was where the check lives. Asking a model to be honest is a hope; checking its answer is a guarantee. So the model returns citations, and native code decides. A quote found word for word is verified. A real line with different words is shown as AI interpretation. A citation to a line that doesn't exist is dropped, and the count is shown rather than hidden.

Meeting notes with a promise and a decision, each linked to a timestamp
The cited line lights up in the transcript. Click any line to hear it.

2. My promises

What: a list of the things you said you'd do, across every meeting, with due dates. Why: that's the list people actually need on a Friday afternoon, and models are generous with ownership. So the rule is strict and written in code: the model says you own it, the quote is verified, and the line came from your own microphone track.

My promises · decided by code, not the model

The list people actually need after a meeting is what they said they'd do. A wrong entry there costs trust fast.

“I'll send the revised booking cards by Friday.”0:41 · your microphone

  1. ✓ The model says the owner is me owner = me
  2. ✓ The quote is word for word in a real line verified
  3. ✓ That line is on my microphone track, not echo speaker = you
In My promisesAll three checks passAdded to My promises, due Friday, with the quote you can replay.
The Today screen, with capture options and My promises
Today: start a capture, see what you owe.

3. Honest capture

What: the recording lifecycle lives in the native layer, and the interface only shows what it reports. Why: the worst failure a notetaker has is silent. It only says Recording once the first real audio arrives. Pure silence becomes “No sound coming in” after 1.5 seconds. Audio is written in 30-second chunks with the header rewritten every second, so a crash costs about a second.

Capture · say Recording only when it's true

The worst thing a notetaker can do is look like it's recording when it isn't. You only find out after the meeting.

  1. Idle
  2. Preparing
  3. Recording
  4. Stopping
  5. Finalizing
  6. Problem
Ready to recordAlways let people know before you record them.
MicrophoneCall audio
  1. Start capture pressed.
A normal meeting · step 1 of 6Ready to recordAlways let people know before you record them.
The menu bar popover while recording
The timer sits in the menu bar. Two meters, two tracks.

4. Private by default

What: speech becomes text on the Mac with Whisper. Notes are optional, use your own Anthropic key from the Keychain, and send transcript text only. Why: people are recording their colleagues, so the default has to be that nothing goes anywhere. Separate tracks also mean “you” and “others” come from the track, not from guessing voices.

Privacy · what leaves this Mac

People are recording their colleagues. The default has to be that nothing goes anywhere.

Your Mac
Transcript text onlyClaude, with your key

Leaves this Mac: nothing. Audio: never.

Notes offNothing leaves the MacYou still get a searchable transcript you can replay. Notes are opt-in.
Settings for on-device transcription and notes
Settings say what runs where, what it costs, and what leaves.

5. Decisions that keep their history

What: a trail of decisions across meetings, with links like Replaces it, Builds on it and Conflicts with it. Why: plans change, and a tool that quietly overwrites the old answer makes every argument about who said what. pebbl. never rewrites history. It suggests a connection from shared wording, changes nothing until you choose, and keeps an append-only record.

Decisions · never silently rewrite history

Decisions drift across meetings. Notes tools overwrite the old answer. pebbl. keeps both, and asks you how they relate.

Sun, Oct 11 · Walkthrough: new booking cards
Ship to staging on Friday, web onlyAgreed2:31 “I'll ship them to staging on Friday”
Possibly connected to “Ship on web first in October”. Similar wording: ship, web.
Sun, Oct 11 · Booking cards: dates upfront
Show availability dates upfront on booking cardsAgreed0:25 “Let's show availability dates upfront on the card itself”
Ship on web first in OctoberProposed0:41 “October works if we keep it to web first”
SuggestionPossibly connected to an earlier decisionSimilar wording: ship, web. Computed on the Mac from the words alone, shown on the newer decision only. Pick how they relate.
The decisions trail with a suggestion to review and a confirmed replacement
Trail: a suggestion waiting for a choice, and a replacement that kept the old decision.
The decision map, with meetings by date and links between decisions
Map: superseded decisions stay visible, struck through, still clickable.

The Trail shipped first and the Map second, on purpose. A graph drawn before the data model works is decoration. Once links and history held up in tests, the Map became a second way into the same facts, with a screen-reader list stating every connection in words.

Wireframes

I wireframed nine screens on the same grid as the final build, so each numbered note sits on the same element in both. Switch between Wireframe and Built to see what changed, and what didn't.

Wireframes · nine screens, one grid

Drawn low-fi first, then built on the same grid. Every number sits on the same element in both views.

The menu bar popover while recording
Menu barWhy this screenThe menu bar is the product. Everything you need mid-meeting fits in one popover, and it works with the main window closed.
A screen recording walkthrough with sharing options
Walkthroughs go through the same pipeline, so a video arrives with a transcript and chapters.
Searching meetings
⌘K search across titles, notes and every transcript line.

The design system

  • Mineral warmth. Chalk and paper surfaces, ink text. Moss means live and healthy, clay means recording, slate-blue means evidence.
  • Never colour alone. Every status pairs a colour with a word and a shape. Problems use a square marker.
  • Contrast is tested. The muted grey was darkened until it passed WCAG AA on every surface, and a test checks the pairs in both themes.
  • Motion has a job. Still when idle, breathing while listening, a slow drift while processing, and static for errors. Reduce Motion is respected.
  • Licensed type. Geist, bundled locally under the OFL. Timestamps in the system mono.

How it was built

I wrote the spec first, and that's where most of the design happened: positioning, jobs to be done, what V1 must do, what it must not pretend to do, and phases with exit gates. Then I built it with Claude in one sitting, logging each decision as it was made.

  1. Phase 0Foundation

    Tauri shell, menu bar, popover, design tokens with contrast tests.

  2. Phase 1Capture

    Microphone and call audio to crash-safe files, with recovery.

  3. Phase 2Evidence

    On-device transcription, checked notes, Evidence Mode, My promises.

  4. Phase 3Library

    Search, editing, export, retention, shortcuts.

  5. ThenScreen and brand

    Screen recording, the brand system, chapters, the decisions trail.

  6. Phase 5Decision graph

    Links, append-only history, suggestions and the Map.

The non-goals mattered as much as the features. V1 refuses to pretend it can capture every meeting automatically, tell every voice apart, be perfectly accurate, or get consent on your behalf. Saying no is what kept a one-day build honest.

Validation

An app about not overclaiming shouldn't overclaim about itself. The status file uses one rule: “tested” means verified by a named command in a named environment. Here's where each piece stands.

Validation · the project shows its receipts too

An app about not overclaiming shouldn't overclaim about itself. Every feature says how far it has been checked.

FeatureBuilt
17/17
Automated tests
13/17
Run on a Mac
1/17
200 automated tests97 Rust, 103 frontend“Tested” only ever means verified by a named command, in a named environment. Pick a row to see how.

What I learned

  • The spec was the design work. Writing down the non-goals and exit gates did more for the product than any screen.
  • Trust is mostly what you refuse to show. A dropped citation, a hidden echo line and a missing promises list are all features.
  • Building in the real material surfaces real decisions. “Recording only after the first buffer” and echo removal never come up in a mockup.