Skip to content

Suggest calendar invitees as names in speaker review - #1853

Merged
r3dbars merged 4 commits into
mainfrom
claude/calendar-aware-naming-av9y3k
Sep 25, 2026
Merged

r3dbars merged 4 commits into
mainfrom
claude/calendar-aware-naming-av9y3k

Conversation

@r3dbars

@r3dbars r3dbars commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

Requested by Justin · project thread

Why

Before: after a meeting, speaker review asks "who is Speaker 1?" and you type every name, even though your calendar already knows who was on the call.

After: when the recording started with a calendar event, that event's invitees show as one-click name buttons on each review row and sit at the top of the name list. In a 1:1 where the meeting heard one remote voice, the other invitee's name is filled in; you still press Save.

"Started with" means the recording began in the same window the "record this meeting?" pop-up uses: from a minute before to five minutes after the event's start. It doesn't matter whether you started from the pop-up or the hotkey (Justin's pick). A call that just falls inside a long calendar slot gets no names. For example, if a 1-hour meeting ends after 15 minutes and someone else calls at minute 30, that call gets no suggestions (Justin's ask).

This is option A from Justin's naming brainstorm: suggestions only. Silent auto-naming (0.92 similarity, 0.12 margin, 5 confirmed meetings) is unchanged. Option B (fewer confirmations when the calendar agrees) waits for an eval.

Product Impact

  • Affects: meetings
  • Lane: meeting reliability
  • Why this matters: cuts the typing that every new person costs today, and it's the first step toward names that pay off elsewhere (Context plan).

What changed

  • Sources/Support/MeetingInviteeSuggestionPolicy.swift (new, Foundation-pure):
    • Matches an event only when the recording's start falls between MeetingPromptHeuristics.calendarReminderLeadTime before and calendarReminderPostStartGrace after the event's start. Those are the pop-up's own constants, and a test pins them equal.
    • All-day events, events with no other invitees, and double bookings with different people don't count.
    • Cleans invitee names: drops you, rooms, groups, and duplicates. Email-only invitees are dropped unless the email reads like first.last, so a raw email is never shown.
    • Maps an invitee onto a saved person's label when exactly one saved person has that name, and puts invitees first in the list, after "You".
    • Pre-fills a 1:1 only when there is one other invitee, the transcript's system_speakers is 1, and the one remote row has no suggestion. So a guest sitting next to an auto-named invitee isn't handed their name.
  • Sources/Meeting/MeetingInviteeCalendarReader.swift (new): read-only EventKit lookup on a background queue. It only runs when calendar access was already granted and never asks for it. It keeps events with no meeting link, so in-person meetings count, and it includes the organizer.
  • Sources/UI/Settings/SpeakerNamingSheet.swift:
    • Reads the recording's start and system_speakers from the saved transcript's frontmatter off the main thread. Imports carry imported_at and are skipped.
    • Looks up invitees and adds an "Invited:" line of buttons to each row, with 40pt hit targets. A row grows by 48pt only when it has invitees.
    • Picking a button fills the name box. A pick that differs from a confirmed match clears the confirmation, same as typing.
    • A pre-filled row says "Filled in from your calendar invite. Check it, then save." until it's edited.
  • Tests/MeetingInviteeSuggestionPolicyTests.swift, plus its entry in run-tests.sh APP_SOURCES.
  • Local CLAUDE.md file lists updated.

How I checked it

  • bash scripts/dev/linux-checks.sh (48 passed, 0 failed)
  • python3 scripts/dev/check-source-pins.py --changed-only (all pins hold)
  • bash build.sh --no-open / bash run-tests.sh / integration smoke: green in CI on 1a6d2e1; CI is running again on the latest head

Checks I could not run, and why: the cloud session has no Swift toolchain, so CI is the build.

Mac or hardware test still needed? Yes:

  1. With calendar access on, click Record on the calendar pop-up for a meeting with one other invitee. Speaker review should show "Invited: " and the remote row should be pre-filled. On main the row is empty.
  2. Same with a 3-person invite: there should be a button for each of the others and no pre-fill.
  3. Start a recording 20+ minutes into a long calendar slot: there should be no invitee buttons.
  4. Import an audio file: there should be no invitee buttons.
  5. Turn calendar access off: review should look exactly like main.

Risk Review

  • Privacy and local-first behavior reviewed: invitee names are read on demand and held in memory only while the sheet is open. They are never stored, logged, or sent. No analytics or Sentry changes.
  • New analytics properties or Sentry tags: none.
  • Checked the text-pin tests for every file I edited.
  • Storage path or migration impact: none.
  • Public-facing copy stays concrete.
  • Release/update impact: none.
  • Deep review: READY at 1a6d2e1 (reviews/next-release/1853.md). M1 fixed in ac95605. M2 kept, see Notes.
  • UI visuals (needs a Mac run).
  • No private data included.

Notes

  • Deep review M2: .unknown participant types are kept as people. EventKit reports many Google and CalDAV attendees that way, so dropping them would lose real invitees. An untagged room could still show up as a button, but it's only a suggestion.
  • Follow-ups, not in this PR: count button use (counts only), and option B once there's an eval.

Agent handoff

COORD_DONE: BRIEF | this PR | invitee name buttons + 1:1 pre-fill, only when the recording starts with the event | none | none | linux-checks + source pins + CI | CI on ac956058, then Mac check

🤖 Generated with Claude Code

https://claude.ai/code/session_01W3Eka9wHqsZQvPs8X2XAGP

When a calendar event overlaps a saved meeting, its invitees show up as
one-click name buttons on each speaker review row and lead the name list.
A 1:1 with one unnamed remote voice gets the other invitee pre-filled; the
user still presses Save. Suggestions only: silent auto-naming is unchanged.

Invitee names are read from EventKit on demand, only when calendar access
was already granted, and are never logged or sent off the Mac. Imported
recordings are skipped.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W3Eka9wHqsZQvPs8X2XAGP
@r3dbars r3dbars self-assigned this Sep 25, 2026
An event now counts only when the recording started in the same window the
record-this-meeting pop-up uses (a minute before to five minutes after the
event's start). Before, any event covering half the recording counted, so
a second call later in a long calendar slot picked up the first meeting's
invite list.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W3Eka9wHqsZQvPs8X2XAGP
Review rows leave out voices that were already named silently, so one
review row could sit next to an auto-named invitee. The pre-fill now also
needs the transcript's system_speakers to be 1, and skips when that count
is unknown. From the deep review (M1).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W3Eka9wHqsZQvPs8X2XAGP
@r3dbars
r3dbars marked this pull request as ready for review September 25, 2026 17:09
@r3dbars
r3dbars merged commit 1c41d69 into main Sep 25, 2026
8 checks passed
@r3dbars
r3dbars deleted the claude/calendar-aware-naming-av9y3k branch September 25, 2026 17:29
r3dbars pushed a commit that referenced this pull request Sep 25, 2026
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CbeBca5tWoYd38bopu4dF1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants