Files
meeting-assistant/openspec/specs/meeting-recording/spec.md
T
codex 1a89382f02
PR and Push Build/Test / build-and-test (push) Failing after 9m48s
Improve toast duration and speaker override samples
2026-06-05 10:52:08 +02:00

301 lines
19 KiB
Markdown

# meeting-recording Specification
## Purpose
TBD - created by archiving change define-meeting-assistant-v1. Update Purpose after archive.
## Requirements
### Requirement: Recording mode is controlled by a configurable hotkey
Meeting Assistant SHALL use normal .NET configuration to define the global hotkey that toggles recording/transcription mode.
Meeting Assistant SHALL expose a configurable abort/discard hotkey for an active recording.
When aborting an active recording, Meeting Assistant SHALL stop active audio capture and transcription, SHALL remove the meeting note, transcript, assistant context, summary artifact, and linked screenshot attachment files created for that run, and SHALL NOT invoke automatic summary generation.
When no recording is active, aborting SHALL leave the current recording status unchanged.
#### Scenario: Hotkey starts recording
- **WHEN** the configured hotkey is pressed while recording mode is inactive
- **THEN** Meeting Assistant starts recording/transcription mode
#### Scenario: Hotkey stops recording
- **WHEN** the configured hotkey is pressed while recording mode is active
- **THEN** Meeting Assistant stops recording/transcription mode
#### Scenario: Active recording is aborted and discarded
- **GIVEN** a meeting recording is active and has created meeting artifacts
- **WHEN** the user aborts the recording
- **THEN** Meeting Assistant stops recording
- **AND** deletes the meeting note, transcript, assistant context, summary artifact if present, and linked screenshot attachment files for that run
- **AND** does not invoke the summary pipeline
#### Scenario: Abort does nothing when idle
- **GIVEN** no meeting recording is active
- **WHEN** the user aborts recording
- **THEN** Meeting Assistant remains idle
### Requirement: Recording mode captures microphone and computer output
Meeting Assistant SHALL capture microphone input and computer output and combine them into one audio stream for transcription.
Meeting Assistant SHALL capture audio as 16 kHz mono PCM chunks for the existing recording and transcription pipeline.
Meeting Assistant SHALL capture microphone and system loopback as separate input streams before producing the final mono chunks.
Meeting Assistant SHALL clean the microphone stream with a local acoustic echo cancellation stage that uses system loopback as the far-end reference.
Meeting Assistant SHALL produce final mono chunks by adding the cleaned microphone samples and system samples.
Meeting Assistant SHALL align microphone and system samples through per-source buffers before mixing and SHALL NOT emit normal live audio chunks that contain only one source while the other source is merely delayed.
When one source stays quiet beyond the alignment timeout, Meeting Assistant SHALL mix the available source with synthetic silence for the missing source instead of blocking transcription.
Meeting Assistant SHALL allow the final microphone/system mono mix to apply configurable microphone and system gain before combining samples.
Meeting Assistant SHALL use the active run or launch profile recording options when configuring capture format and final microphone/system gains.
Meeting Assistant SHALL clamp mixed samples after gain is applied.
Meeting Assistant SHALL write only the mixed stream to the temporary WAV used by transcription and finalization.
#### Scenario: Both sources produce audio
- **WHEN** microphone and computer output audio chunks are available
- **THEN** Meeting Assistant mixes them into one PCM stream before transcription
#### Scenario: Mixed audio uses cleaned microphone and system audio
- **GIVEN** the echo canceller cleans a microphone chunk to sample `2000`
- **AND** the matching system chunk has sample `10000`
- **WHEN** microphone and system chunks are mixed with gains `1` and `1`
- **THEN** the mixed sample is `12000`
#### Scenario: Temporary recording stores only the mixed stream
- **GIVEN** Meeting Assistant has mixed microphone and system audio into one PCM chunk
- **WHEN** Meeting Assistant appends the chunk to the temporary recording
- **THEN** the main temporary WAV contains the mixed PCM
- **AND** no microphone or system sidecar WAV is written
#### Scenario: Launch profile recording options configure capture and gains
- **GIVEN** an active launch profile configures sample format and microphone/system mix gains
- **WHEN** Meeting Assistant captures and mixes audio for that run
- **THEN** the microphone and system capture sources receive that launch profile recording configuration
- **AND** the mixed output uses that launch profile's microphone/system gains
#### Scenario: Delayed sources are buffered before mixing
- **GIVEN** microphone audio arrives before matching system audio
- **WHEN** matching system audio arrives after a short delay
- **THEN** Meeting Assistant emits one mixed chunk for the aligned samples
- **AND** it does not emit separate microphone-only and system-only chunks for that delayed pair
#### Scenario: Quiet system audio does not block microphone transcription
- **GIVEN** microphone audio arrives
- **AND** system loopback audio does not arrive within the alignment timeout
- **WHEN** Meeting Assistant mixes the available audio
- **THEN** it emits the microphone audio mixed with silent system audio
- **AND** live transcription can continue while system loopback is quiet
#### Scenario: Continuous microphone audio does not suppress the alignment timeout
- **GIVEN** microphone audio keeps arriving
- **AND** system loopback audio stays unavailable past the alignment timeout
- **WHEN** Meeting Assistant checks the buffered microphone audio
- **THEN** it emits the buffered microphone audio mixed with silent system audio
- **AND** it does not wait indefinitely for a loopback chunk
#### Scenario: Device-level capture cannot be verified in tests
- **WHEN** automated tests run without live audio devices
- **THEN** Meeting Assistant verifies the audio mixer through deterministic source abstractions rather than depending on physical microphone or speaker devices
### Requirement: Stopping recording drains captured audio through transcription
Meeting Assistant SHALL stop capturing new audio when recording mode is stopped, but it SHALL allow already captured audio to finish running through the configured speech recognition pipeline before the recording session completes.
When a recording is stopped, Meeting Assistant SHALL stop audio capture for that run and MAY continue draining transcription, speaker recognition, and summary generation for that stopped run.
Meeting Assistant SHALL allow a new recording to start after the previous run's capture has stopped, even if the previous run is still draining transcription, speaker recognition, or summary generation.
Each run SHALL keep its own transcript session, meeting note path, artifact paths, options, audio buffer, live transcript buffer, and speaker mappings isolated from later runs.
Rapidly-created meeting note, transcript, assistant context, and summary artifact filenames SHALL be distinct.
#### Scenario: Hotkey stops recording with buffered audio
- **WHEN** the user presses the hotkey to stop recording while captured audio is still buffered for transcription
- **THEN** Meeting Assistant stops capturing new audio and appends transcription output for the already captured audio before reporting the recording stopped
#### Scenario: New capture starts while previous run is finalizing
- **GIVEN** a recording has been stopped and is still finalizing its transcript or summary
- **WHEN** the user starts another recording
- **THEN** Meeting Assistant starts the new capture
- **AND** final transcription and summary output from the stopped run use the stopped run's files
- **AND** live transcription buffers from the stopped run are not written to the new run
### Requirement: Transcripts are written to the configured vault folder
Meeting Assistant SHALL write live transcript text to a markdown file in the configured vault folder.
#### Scenario: Recording starts
- **WHEN** recording mode starts
- **THEN** Meeting Assistant creates the configured vault folder if necessary and creates a transcript markdown file
#### Scenario: Transcription segment arrives
- **WHEN** the speech recognition pipeline emits a live transcript segment
- **THEN** Meeting Assistant appends that segment to the active transcript text file
### Requirement: Recording can be launched through named profiles
Meeting Assistant SHALL treat the root `MeetingAssistant` configuration as a launch profile named `default`.
Meeting Assistant SHALL allow additional named launch profiles to be configured as overrides of the default profile. A named profile SHALL be resolved by binding the default profile first, then binding the named profile override onto the same option object.
Meeting Assistant SHALL preserve existing recording endpoint URLs as default-profile URLs and SHALL provide equivalent named-profile URLs that include the profile name.
Each launch profile SHALL have a distinct global hotkey. Pressing a profile hotkey SHALL toggle recording using that profile's resolved configuration.
Meeting Assistant SHALL use the selected launch profile's vault and recording storage settings when it creates meeting notes, transcripts, assistant context notes, summary notes, temporary recordings, and dictation-word inputs for that meeting.
Meeting Assistant SHALL use the selected launch profile's summary-agent settings when it runs the summary pipeline for that meeting.
#### Scenario: Default profile keeps existing recording URL
- **WHEN** the user calls the existing recording start URL without a profile name
- **THEN** Meeting Assistant starts recording with the `default` launch profile
#### Scenario: Named profile starts recording
- **WHEN** the user calls the named-profile recording start URL for profile `english`
- **THEN** Meeting Assistant starts recording using the resolved `english` launch profile configuration
#### Scenario: Named profile stores meeting artifacts in profile folders
- **GIVEN** launch profile `english` overrides vault folders and summary-agent settings
- **WHEN** the user starts and stops a recording with launch profile `english`
- **THEN** Meeting Assistant creates the meeting note, transcript, assistant context note, and summary note using the resolved `english` vault folders
- **AND** Meeting Assistant runs the summary pipeline using the resolved `english` summary-agent settings
#### Scenario: Profile hotkeys must be distinct
- **GIVEN** two launch profiles configure the same toggle hotkey
- **WHEN** Meeting Assistant resolves launch profiles
- **THEN** Meeting Assistant rejects the configuration before registering global hotkeys
### Requirement: Active recording can switch launch profiles
Meeting Assistant SHALL allow a launch profile hotkey or named-profile recording toggle request to switch the active meeting to that profile while recording capture is active.
When switching profiles during an active meeting, Meeting Assistant SHALL keep the existing meeting note, transcript, assistant context, summary path, user notes, calendar metadata, projects, attendees, and assistant-context state.
When switching profiles during an active meeting, Meeting Assistant SHALL NOT create new meeting artifacts, SHALL NOT collect calendar metadata again, and SHALL NOT run the summary pipeline for the old profile segment.
When switching profiles during an active meeting, Meeting Assistant SHALL stop and drain the current speech recognition pipeline, append a transcript marker indicating the target profile, start a new speech recognition pipeline using the target profile's resolved options, and continue writing live transcription to the same transcript file.
When audio is captured while the old speech recognition pipeline is draining, Meeting Assistant SHALL buffer that audio and send it to the new profile's speech recognition pipeline after it is ready.
When switching profiles during an active meeting, Meeting Assistant SHALL clear run-local speaker label mappings for future transcript segments because backend speaker IDs can change across speech recognition processes. Already-written named transcript segments SHALL remain unchanged.
#### Scenario: Active meeting switches to named profile
- **GIVEN** a meeting was started with the default launch profile
- **WHEN** the user triggers launch profile `english` while recording is active
- **THEN** Meeting Assistant keeps the existing meeting artifacts
- **AND** drains the old speech recognition pipeline without running summary generation
- **AND** appends a transcript marker for the profile switch
- **AND** starts transcription with the resolved `english` profile
- **AND** continues writing transcript segments to the same transcript file
#### Scenario: Captured audio is buffered while switching
- **GIVEN** a meeting is switching from one launch profile to another
- **WHEN** audio chunks are captured before the new speech recognition pipeline is ready
- **THEN** Meeting Assistant buffers those chunks
- **AND** sends the buffered chunks to the new speech recognition pipeline after it starts
#### Scenario: Switching clears future speaker mappings only
- **GIVEN** a live speaker label was mapped to a named speaker before switching profiles
- **WHEN** Meeting Assistant switches to another launch profile
- **THEN** already-written transcript text keeps the named speaker
- **AND** later transcript segments from the new pipeline do not reuse the old backend speaker label mapping
### Requirement: Windows taskbar icon controls recording
Meeting Assistant SHALL show a Windows taskbar notification icon when running on Windows.
The taskbar icon SHALL indicate whether the newest meeting process is idle, actively recording, or post-recording processing/summarizing.
When a new meeting is actively recording while an older stopped meeting is still transcribing, recognizing speakers, or summarizing, the taskbar icon SHALL show the new active recording state.
The taskbar icon right-click menu SHALL expose recording controls based on the current state and configured launch profiles.
When Meeting Assistant is idle or only processing older stopped meetings, the menu SHALL allow starting a meeting recording for each configured launch profile.
When a meeting is actively recording, the menu SHALL allow stopping the recording and continuing transcription/summary generation.
When a meeting is actively recording, the menu SHALL allow canceling the recording and discarding that run's artifacts.
When a meeting is actively recording, the menu SHALL allow switching to each configured launch profile other than the current active profile.
#### Scenario: Idle tray menu can start configured profiles
- **GIVEN** launch profiles `default` and `english` are configured
- **AND** no meeting recording is active
- **WHEN** the taskbar menu is opened
- **THEN** it offers start recording actions for `default` and `english`
#### Scenario: Recording tray menu exposes stop, cancel, and profile switches
- **GIVEN** launch profiles `default` and `english` are configured
- **AND** a meeting is actively recording with profile `default`
- **WHEN** the taskbar menu is opened
- **THEN** it offers stop and cancel actions
- **AND** it offers switching to `english`
- **AND** it does not offer switching to `default`
#### Scenario: Active recording has priority over older summarizing runs
- **GIVEN** an older meeting is still summarizing
- **WHEN** a newer meeting is actively recording
- **THEN** the taskbar icon indicates recording
### Requirement: Recording inactivity safeguard stops forgotten meetings
Meeting Assistant SHALL track transcript inactivity during an active recording from the later of meeting start or the most recent live transcript segment that contains text.
Meeting Assistant SHALL show a stop prompt when transcript inactivity reaches configured prompt thresholds. The default thresholds SHALL be 2 minutes, 5 minutes, and 10 minutes.
On Windows, the stop prompt SHALL use a native Windows app notification with affirmative and negative action buttons.
On Windows, the stop prompt notification SHALL request reminder-style toast behavior and remain actionable for 1 minute.
The stop prompt SHALL ask whether to stop the meeting and SHALL provide affirmative and negative actions.
Showing or ignoring the stop prompt SHALL NOT block later inactivity checks, reminder prompts, or automatic stop.
If the user accepts the stop prompt, Meeting Assistant SHALL stop the recording normally, allowing transcription, speaker recognition, and summary generation to continue as for a normal stop.
Meeting Assistant SHALL automatically stop the recording normally when transcript inactivity reaches the configured auto-stop threshold, defaulting to 30 minutes.
When the inactivity safeguard stops a recording, Meeting Assistant SHALL infer the meeting end time from the most recent transcript segment timestamp plus configured padding, defaulting to 1 minute. If no transcript segment has arrived, Meeting Assistant SHALL infer the end time from the meeting start time plus the same padding.
When a recording stops normally and its meeting note, transcript, and assistant context contain no user-authored or captured content beyond generated default headings and metadata, Meeting Assistant SHALL delete the run artifacts instead of running summary generation.
#### Scenario: Inactive recording prompts the user
- **GIVEN** a recording is active
- **AND** no transcript text has arrived for the first configured inactivity prompt threshold
- **WHEN** the inactivity safeguard checks the active recording
- **THEN** Meeting Assistant prompts the user whether to stop the meeting with a native Windows app notification when running on Windows
- **AND** the notification remains actionable for 1 minute
- **AND** does not abort or discard meeting artifacts
#### Scenario: Ignored inactivity prompt does not block auto-stop
- **GIVEN** a recording is active
- **AND** the inactivity safeguard prompt was shown
- **WHEN** the user ignores the prompt until the automatic stop threshold is reached
- **THEN** Meeting Assistant stops the recording normally without waiting for a prompt response
#### Scenario: User accepts inactivity stop prompt
- **GIVEN** a recording is active
- **AND** the inactivity safeguard prompt is shown
- **WHEN** the user chooses to stop the meeting
- **THEN** Meeting Assistant stops the recording normally
- **AND** continues normal transcription and summary processing
- **AND** writes the inferred meeting end time to meeting artifacts
#### Scenario: Inactive recording automatically stops
- **GIVEN** a recording is active
- **AND** no transcript text has arrived through the configured automatic stop threshold
- **WHEN** the inactivity safeguard checks the active recording
- **THEN** Meeting Assistant stops the recording normally without aborting artifacts
- **AND** writes the inferred meeting end time to meeting artifacts
#### Scenario: New transcript text resets inactivity prompts
- **GIVEN** a recording is active
- **AND** the first inactivity prompt was shown
- **WHEN** a new transcript segment with text arrives
- **THEN** Meeting Assistant resets the inactivity prompt schedule from that transcript arrival
#### Scenario: Empty stopped recording is cleaned up
- **GIVEN** a recording is active
- **AND** the meeting note, transcript, and assistant context only contain generated default content
- **WHEN** the recording stops normally
- **THEN** Meeting Assistant deletes the run artifacts
- **AND** does not run summary generation