Repository navigation
Split the hotspot files - #1950
Conversation
Four Core audio tests read Sources/ as text. Each now checks the promise it was guarding through real calls: - Mic stop tail: a buffer delivered the instant stop() advances the generation is still saved. Fails if mic admission is armed after the bump. The old "close only in closeMicrophone" pin is already covered by the end-to-end test in the same file (closing earlier drops its tail). - System stop tail: real Audio.stop() saves a buffer delivered at the generation bump and one still in the ring. Fails if beginFinishing moves after the bump or stop cancels instead of finish-and-drain. - Mic-only diagnostics: with the last meeting's tap still stored, every tap-derived snapshot field is blank on a mic-only meeting. - Mic-only start: makeSystemAudioCaptureForRecordingAttempt returns nil and never calls the factory on a mic-only recording. Seams, same behavior: the mic-only gate moved from startAudioCapture into makeSystemAudioCaptureForRecordingAttempt (its only caller, no else branch), and beginRecordingSessionGeneration calls an optional test hook after the bump, outside the lock. Nil in the app; start/stop path only, not a real-time callback. Each new test was checked against the regression it guards.
FocusOrderContractTests no longer reads Sources. It builds the real menu bar row and section views and checks they take focus, activate on Space/Return/Enter, and hand over rows in the declared Tab order. The popover's key-view loop moves into MenuBarKeyViewLoop so the test can check the chain and wrap. MenuBarUtilityActionsView takes a closure for "is dictation loaded" instead of the whole app state, so it compiles in the fast runner; same value as before. The sidebar's primary row order is checked from SettingsSidebarSection.primarySection. The pin on .accessibilityIdentifier(page.automationIdentifier) is dropped: UI smoke (TranscriptedQA UISmoke) finds those sidebar identifiers in the live app, which is the real promise. StatusItemPresentationTests now compares the tail curves the glyph really draws with the generator's Q commands instead of grepping MenuBarGlyph.swift. Its TranscriptedApp.swift pins stay for now.
…ests Small seams, same behavior: - SharedMeetingMicRecorder.recordBorrowedBuffer(_:meter:) is now the whole body of appendSharedMeetingMicBuffer; the test shows borrowed PCM is recorded even when the level meter is idle. - PinnedDictationInputPolicy.pinnedSelection(...) holds the pinned mic pick; tests cover headset skipping, "Same as macOS" keeping AirPods, a picked mic winning, and a dead pick being excluded. No device or engine change, so a Bluetooth default input is handled exactly as before. - DictationVoiceProcessingRoutePolicy.isRequested and ParakeetMicrophoneSharingPolicy.mayDowngrade carry the call-app VPIO rules. - forceForMicrophoneSharing moved into the echo, probe and graph policies as a required argument, so a call-app downgrade's bypass is tested directly. Deleted the "never calls MicrophoneProcessingPreferences.set" pin: the VPIO decision is now a pure read of the saved value, and the test shows VPIO comes back when the call app closes. Wiring and AVAudioEngine call-order pins stay until ParakeetEngine can be built in tests.
Pulled the decisions out into small compiled seams and test those: - MeetingSessionStateMachine.startAdmission: Record is turned away while a capture is starting/recording/stopping, or a start is in flight. - MenuBarMeetingMenuAction: the menu button means Stop for the whole capture, and a Stop while starting joins the pending start. - MeetingSleepWakeNotificationSource: capture listens on the workspace center with the real NSWorkspace sleep/wake names. - Publisher.wholeSecondTicks: the menu bar's duration refresh fires once per whole second (fed fake 5 Hz ticks). - HomeFailedMeetingRowActions: Show Audio for any kept file, retry only for complete retryable audio, cleanup is a destructive delete. Deleted the two TranscriptionQueueCoordinator pins. They only checked that two function names existed; the compiler already guarantees the public one, and the private no-arg finalize overload had no callers, so it's gone too. No behavior change.
…vior EventReporter.capture's decisions move into ObservabilityEventCapturePlan, a pure function the fast runner compiles: build identity stamping, the raw entry for the reliability recorder vs the blanked disk copy, PostHog forwarding from the caller's context only, and the Sentry policy. EventReporter just runs the plan; same sinks, same values. EventLevel moves with it. EventFileWriter moves to its own file with an injectable file URL, so tests can check a buffered info event lands on shutdown flush and a pre-existing events.jsonl is made owner-only. AppLogSink takes an optional log URL (default unchanged) and imports TranscriptedCore only when it can, so the test checks what log() stores is redacted. The console-path pins become a check that prepare failures hand the callbacks a message with no absolute path. PasteLastDictationFeedbackPanel is no longer private, so the overlay privacy test builds one and checks sharingType instead of slicing text. Still source-read, for later: EventReporter/TranscriptedApp shutdown flush wiring and the legacy FileHandle API sweep.
The dictation controller can't run in the fast tests, so the decisions it makes after Stop move into small compiled policies and the tests call those. Behavior is the same. New seams: - DictationSessionCapFinish: the cap finalizes (never discards) and pastes only when the original app is still in front. - DictationSessionCapSavePolicy + completionProperties: cap save notice, Paste It result, and the dictation_completed delivery/failure keys. - DictationStopRoute: early-release cancel, "Still finishing", recovered audio going on to transcription. - DictationDeliveryPresentation + TextPasteOutcome.deliveryProperties: what the pill shows after a paste, and one delivery value for diagnostics and analytics. - DictationInterruptionPlan, DictationTerminationFinisher, DictationRetainedAudioRetry: interruption offer, Quit ordering, Retry Saving ordering, run with fakes. - DictationEarlyReleaseCancelReport: the .error event that reaches Sentry. EventLevel moves to ObservabilityEvent.swift so the fast tests can see it. - FocusedTextPasteConfirmationPolicy.boundedFocusedElement: AX timeout and the CFGetTypeID guard, driven with a fake AX reader. Pins deleted, not converted: - OverlayHeaderView "Dictation saved only" VoiceOver copy: no path shows a "Saved only" success title any more (the cap uses showSavedNotice), and the mini cursor view is slated for removal after #1946. - canImport(TranscriptedCore) guard in ClipboardRestoringTextPaster: the fast test compile already fails without it. - Absence pins on old names (Paste Again, pasteConfirmationUnavailable*): the delivery presentation tests now show a likely paste never offers a second paste. ContextCaptureEnginePolicyTests and DictationStartReadinessTests had pins on the moved code; those assertions now call the new policies. Still source text: FloatingOverlayController and TranscriptedApp (open #1946), startDictation's capture guard and the stop path's checkpoint wiring (shared stop/start pipeline seam), the sound-cue counts, feedback silence, the meeting stop terminal, and SpeakerFinalizationFailure raw values.
…r tests ContextCaptureEnginePolicyTests and ExistingInstallModelPrefetchPolicyTests no longer read Sources/ as text. The decisions they guarded now live in small compiled seams with the same behavior, and the tests call those: - HotkeyActionDebouncer + PhysicalShortcutAction.hotkeyDebounceID: per-action repeat guard, push-to-talk never debounced, same telemetry ids. - PhysicalShortcutMatcher.configuredBindings(userDefaults:): the binding snapshot (meeting + paste always, dictation shortcuts first when on). - PhysicalShortcutMatcher.reconcileAfterTapDisabled / isPhysicalKeyDown and a keyState overload of shouldActivateDelayedModifierPress: missed push-to-talk release after the tap is turned off, and bound-key checks for delayed presses. - PhysicalShortcutTriggerStatus: tap failure text, Accessibility retry gate, and the one-banner rule (Fn conflict is advisory, not a registration error). - DictationIgnoredStopFeedback.showsStillFinishing: ignored stop while a take is finishing still says so. The message literal stays at the call site because DictationSessionCapTests (b07) still pins it. - ExistingInstallModelPrefetchPolicy.launchWarmupEnabled(environment:): models warm at launch unless TRANSCRIPTED_LAZY_MODEL_WARMUP is exactly "1". Dropped without a replacement, because no runtime behavior can be checked here: - "no bindingProvider" negative grep: the detector only takes a snapshot now, and the snapshot test covers what it builds. - cancel-pending-before-reconcile and CGEventSource call-shape greps: the physical-state query is now an injected closure covered by the seam tests. Still untested in the fast runner (needs the real engine/app): the tap's dedicated run-loop thread, the Accessibility polling loop calling reRegisterHotkeys, lock-held delayed press delivery, unregister keeping onPasteLastDictation, wake recovery reading hotkeyRegistrationError, and the launch warmup's meeting-model step and task priorities.
STT routing and stopped-audio recovery. Small pure seams, same behavior: - SegmentedEngineTranscript: Whisper's join/trim plus custom dictionary. - DictationLanguageScriptPolicy.unexpectedScript with a lazy language reader, so the router's Carbon lookup only runs for non-Latin text. - DictationEmptyInferencePolicy: external-engine empty/failure reasons and the reason after an empty conversion (both ParakeetEngine call sites). - TranscriptionLanguageModelErrors: the saved-language settings-fix errors, tested against MeetingFailureKind. - STTRouter's load-progress wait switches on runtime. Dropped pins that only matched a declaration (recoveredRecordingTimeline, preserveCurrentRecordingBuffersForRecovery, clearRecoveredRecordingTimeline, interruptRecordingAndClearRecoveredTimeline, drainRecordedSamplesForInference): the compiler already enforces them, and the timeline is covered by RecordedAudioTimelineTests. The Apple Speech "wired through every switch" pins are covered by exhaustive switches. setActiveRecordingModel has no await, so its in-function order was unobservable; the real promise (the lease's variant wins) is now tested through the ownership types. DictationSessionController, MeetingSessionController, TranscriptedApp and a few ParakeetEngine/STTRouter ordering pins stay for the shared pipeline seam.
…r behavior tests The b03 suites read ParakeetEngine, ParakeetZombieEngineRecovery and ParakeetDeviceRecovery as text. Pulled the decisions into small compiled pieces and test those instead. Behavior is unchanged. - ParakeetASRInferenceGate: the decoder gate, moved out of the engine. A caller arriving during a handoff now provably waits behind the resumed waiter. - ParakeetZombieEngineRecoverySequence: the order of the one bounded zombie retry (idle, owner check, recreate, settle, restart once, one terminal result), driven by injected steps. Also the duplicate-detection guard and the "a start cancels recovery unless it's the recovery's own" decision. - ParakeetRecordingContinuityPolicy: when a start gets a fresh recording identity, and what an idle stop does (recovered speech beats a pending zombie restart). - ParakeetDeviceRecoveryFailurePolicy.graphRepair(after:): keep / rebuild / abandon after a failed rewarm. Dropped without replacement: the hasRecoverableRecording existence pin (the compiler already enforces it through STTRouter and DictationSessionController). Still unconverted, waiting on the shared audio-graph driver seam: zombie graph recreation internals, the startRecording audio-start lease, stop/config-change "invalidate and cancel in one actor turn", wake-time buffer preservation, and the device-recovery restart wiring.
…ests Three pieces of ParakeetEngine now live in compiled types the fast tests can drive with fakes. Same behavior, just moved: - the timed engine-work runner -> ParakeetTimedAudioEngineWorkLimiter.run - the single-flight stop -> ParakeetSingleFlightLifecycle - system-input late-completion reconciliation -> ParakeetSystemInputReconciler ParakeetEngineWorkLifecycleTests covers what the pins guarded: a claimed start never touches the engine, mid-flight cancellation cleans up on its own worker, a wedged start times out and gets late cleanup, a full limiter fails closed, duplicate stops join one drain and the stop stays visible until it ends, CoreAudio error strings are retried rather than taken as success, passes are bounded, late completions only re-run when intent changed, and requests drain through one coalescing task. Mutation-probed: each guard flipped turns the suite red. The source-text suites for the system-input reconciliation and duplicate stops are gone, plus the timed-work and stop-intent pins in two other suites. The rest of the file still needs the audio-graph driver seam.
Meeting mic start and the in-meeting Boost now go through small policies in Sources/Meeting/MeetingMicCapturePlan.swift (start plan, next-meeting boost look-past and use-up, and the Boost arm steps behind closures). The bridge calls them with the same reads in the same order, so behavior is unchanged. The fast tests check those policies against a fake capture instead of grepping MeetingCaptureBridge.swift. RetainedDataSourceComboBox now keeps its source alive on a plain dataSource assignment too. Nothing assigns that way today, so the app acts the same, and the "use setRetainedDataSource, not .dataSource =" pins on the speaker name boxes guard nothing anymore. A test covers the plain assignment instead. Dropped pins: - "Boost must not save the mode": the arm steps take only capture hooks, so there's no path to the saved preferences left to pin. - HomeView "secondaryAction*" names: HomeSettingsPage passes those labels, so the compiler already fails if they go. Still source-text (targets are owned by open PR #1946 or are SwiftUI views the fast runner can't build): the Home row and settings pins, the Settings mic picker pins, the Home Boost row negative pin, and the SpeakerNamingSheet self-data-source pin.
BluetoothRouteContractTests read ParakeetEngine, ParakeetDeviceRecovery and PersistentDictationInputController as text. Most of those promises now run through small compiled seams with fakes. Behavior doesn't change. Seams (all in files the fast runner already compiles): - ParakeetDictationTapPreparation: remove tap, apply VPIO, then pick the tap format from the live node and its actual VPIO state. Fake input node. - ParakeetDictationInputSnapshotRead: bind the app's own AUHAL input before any format read (the AirPods call-mode trap). Fake graph. - DictationInputBindingSequence + DictationInputSelectionReportPolicy: a failed bind throws before readiness, success is reported only after a verified settle. - RecordedAudioTimeline.speechSamples: each segment resamples from its own rate. - ParakeetConfigChangeAdmissionPolicy (post-lookup recheck), ParakeetConfigChangeGraphPolicy.action, ParakeetConfigChangeDebounce. - DictationPersistentInputRefreshScheduler, ShutdownPolicy, RestorePolicy: the Mac-wide input write waits out dictation, meetings and other apps' capture, coalesces bursts, and quitting never touches another app's call. applyPreferredDictationInputDevice is now nonisolated: it already ran on the audio-engine queue, and the adapter calls it from there. Deleted the "system input override restores after recording" suite. Nothing arms pendingSystemInputRestore since the 2026-08-24 audit (Speech/CLAUDE.md says so), so every restore call it pinned is a no-op, and the rest were absence checks on the retired temporary crash marker. Still source text, since the code can't compile in the fast runner: the main-actor ordering in audioInputSnapshot, the persistent controller's listener and shutdown wiring, and the QA report doc check. Two assertions in ParakeetMicrophoneSharingSourceContractTests moved to the new behavior tests. Mocked routes only; real AirPods still need bash check.sh hardware.
Stacked on b07 (claude/cleanup-unpin-b07). b07 had already built
DictationStopRoute, DictationEarlyReleaseCancelReport and
DictationTerminationFinisher on the same controller code, so this reuses
them instead of adding second copies. Behavior is the same.
New seams, all in files the fast tests already compile:
- DictationNativeMicrophoneStart: the native open shared by the fast start
and the recovery loop (stage reports, recovery vs ordinary start, focus
recovery only after a failed open). DictationSession's start functions no
longer default isCurrentSession/onStartStageChanged/onStartFailed, so the
recovery loop can't silently drop one.
- DictationStartActivationRecoveryGate: focus recovery at most once per
session, keyed on the session id (replaces didAttemptStartActivation).
- DictationPendingStartStage + DictationPendingStartStageClock: named stages,
session-scoped stage reports, and end() reads and resets in one step.
- DictationProcessActivityLabel: the App Nap reason goes back to "stop
finalization" when a session ends, so the two readmissions no longer set it
by hand.
- DictationStartReadinessPolicy.preparedDiagnostics: start diagnostics name
the key action only when a shortcut started the take.
- DictationHotkeyRouter: Push to Talk and hands-free keys to session
commands, with the real shortcut on each.
- DictationStopRequestRouting: no session, hands-free next press, then the
finalizing fence, before b07's DictationStopRoute.
- DictationQueuedStartGate + DictationQueuedStartPolicy.previousLeftMessage /
drop: Quit blocks queueing, refused Quit reopens, a dropped press is counted
and stays quiet over a take still transcribing.
- DictationFastStart, DictationRecordingStarted: dictation_started only after
the open succeeds; every start drops its start handle.
- DictationInterruptedAudioReadmission: wait for the old checkpoint, check
ownership, then reset the fence.
- DictationStartAdmission.beginSession: the session id is minted after the
request is counted.
- ModelWarmupOutcome.startFailureKind: model_load_failed / model_load_timeout.
Pins deleted, not converted:
- "activationPrepared" absence and "no startActivation.prepare in
beginDictationRecording": absence pins on removed code. The runner tests
already show a healthy open never activates.
- The recoverBackgroundHotkeyStart call count: onStartFailed is now a
required argument on both native start paths, so the compiler holds it.
- "app_nap_suppressed" absence: the report test checks the exact key set.
- HotkeyPreferences absence pins: diagnostics and the early-release report
take the key action as an input.
- The enterPendingStartStage("...") string pins: stages are an enum now.
Still source text: the Esc drop callback and the overlay's
messageCanGiveWayToNextStart reset (FloatingOverlayController, open #1946);
startDictation's countRequest/countRefusal/beginSession wiring and the
isRetry count on Try Again restarts (controller can't build in fast tests);
MeetingSessionController's unexpected-stop handler (also pinned in
MeetingSessionUIPolicyTests, b09's lane; convert together).
# Conflicts: # Tests/ParakeetMicrophoneSharingSourceContractTests.swift
# Conflicts: # Sources/UI/Overlay/DictationRecordingStartOverlayPolicy.swift # Sources/UI/Overlay/DictationSessionController.swift # Tests/ContextCaptureEnginePolicyTests.swift
# Conflicts: # Sources/Observability/EventReporter.swift
b05's externalEngineEmptyReason in ParakeetShortAudioGate now calls it.
Moving the timed runner out of the main-actor engine (b02) added a concurrency warning for the captured didResume var. A small Sendable gate holds the flag instead; same once-only resume. Speech census 25 -> 19.
The file was 2,345 lines with two runners and their models in it. Code moves verbatim along type boundaries in the same Commands/ folder: - PackagedAppSmoke.swift: the command, check/report types, process runner - PackagedAppSmokeRunner.swift: the packaged-app checks and its private helpers - FirstRunReliabilitySmokeRunner.swift: scenarios and how they're judged - FirstRunReliabilityLaunch.swift: one isolated app launch, as an extension - FirstRunReliabilityReport.swift: report and app-report Codable models - PrivacyLogScanner.swift: the log privacy scanner Only access changes: fileManager, timeout, launch, the four seed helpers and the three launch structs go from private to internal so the two runner files can share them. No behavior change.
TranscriptIndex.swift was 1,876 lines. It now keeps the connection, schema gate, reconcile, and per-file indexing (582 lines). The query code moves verbatim into four extensions: - +MeetingQueries: utterance search, speaker history, meeting lists, who_is - +DictationQueries: dictation days, entry search, recent entries - +Context: cross-kind search/recent feed and index counts - +SummaryRollups: summary items, action items, decisions, digest Pure move. Eight members go from private to internal because private is file-scoped: SQLITE_TRANSIENT, bind, colText, colTextOptional, dbError, ftsQuery, MeetingQueryRow, queryMeetings. The e2e smoke source list gains the four new files.
Audio.swift was 3,135 lines. It's now the class shell (stored state, generation token, inits, publisher wiring, deinit) at 813 lines, and the methods moved verbatim into ten Audio+*.swift extensions plus AudioCaptureTypes.swift for the top-level types. Largest new file is 480 lines. No behavior change. Lines moved byte-for-byte; the only edits are dropping `private` on stored state the moved code reads (extensions in other files can't see it) and `public private(set)` -> `public internal(set)` on startFailureStage and systemAudioStartPermissionExplicitlyDenied, still read-only outside the module. Lock scopes, lock order and stop() ordering are untouched. AirPods: no engine or inputNode code changed, it only moved to Audio+MeetingInputGraph.swift, so a Bluetooth default input behaves exactly as before.
Pure move, no logic changes. HomeView.swift drops from 1,708 to 750 lines. The view model, value types, feedback types, scan-warning card and the day-grouped capture list each get their own file. Row actions, the failed-meeting row, the feedback sheet and Load more stay in HomeView.swift for now: UIAutomationSurfaceContractTests still reads their text from that file, and that test is in open PR #1946.
Review of #1949 found these were dropped though the PR said they stayed. They're back as extra assertions on reads the suites already make, so the source-text count doesn't grow. Also fixes the EventLevel comment (pinned-mic events reach PostHog at any level) and brings the source-text inventory up to date.
The 3,000-line file is now the class shell, lifecycle state, status publishers, and completion/cancel/shutdown (~620 lines), plus six extensions in the same folder: +Start, +FailureClassification, +FailedAudioRetention, +OrphanedRecordingRecovery, +Retry, and +CleanupPaths. Bodies moved as-is. Access only widened where a move forced it (private to internal, nothing public). `tasks` and `TaskLifecycleState` stay private: the other files go through three one-line helpers (beginTaskLifecycle, forgetTaskLifecycle, lifecycleOwnedAudioPaths) that hold the exact same expressions.
Moves whole members out of the 1,954-line hotspot, no logic edits. The main file keeps transcribeMultichannel (951 lines). New siblings: +MicrophoneOnly, +MicDiarization, +Stages, +LastChanceSweep. longestAudioDuration and audioDuration go from private to internal, since both entry points now live in different files.
Pure move. ParakeetEngine.swift (3,345 lines) is now a 668-line core (stored state, graph identity, rebuild/abandon, observers, cleanup, deinit) plus seven extension files: InputReadiness, InputRoute, AudioTap, RecordingStart, RecordingTeardown, DictationTranscription, ASRInference. Function bodies moved byte for byte; access widened only where a cross-file caller forced it. Source-text contracts that sliced the old file now read the engine's files together through readParakeetEngineSource(), with end markers moved to the next declaration in the same file. No pins added.
Pure move, no behavior change. The two lock registries get their own files, and the naming flow splits into planning, apply, request queue and finish extensions. Five members go from private to internal so the flow can span files: PlannedNamingChanges, planNamingUpdates, liveProfileConfirmations, shouldApplyNoDialogDatabaseMutation, cleanupNamingArtifacts.
Pure move, no behavior change. The 4,412-line hotspot is now 13 files, none over 850 lines. - MeetingSessionController.swift keeps start, stop, the unexpected capture stop, the stop snapshot and signal verification. Those had to stay put: UIAutomationSurfaceContractTests pins them by path and that file is in another open PR. - MeetingSessionController+State.swift now declares the class: stored and published state, init, transition and updateDisplayStatus. - The rest moved to +Types, +RecordingStart, +CancelAndTermination, +MicBoost, +LiveCaptureWarnings, +ModelWarmup, +TranscriptionRequests, +Subscriptions, +TranscriptionOutcomes, +Telemetry, +FailedMeetings. Function bodies are byte-identical; the only code edits are access modifiers. Members used across the new files lost `private` (or `private(set)`); state, displayStatus, failedMeetings, warmupStatus and the other writer-owned values stay private(set). Tests: source-text pins on text that moved out of the file are dropped, not re-pinned (skipped-outcome error, recovery cleanup, prompt outcome count, retranscribe preference, capture-stop evidence stash). The handleUnexpectedCaptureStop needle drops "private". Test-shape baseline shrunk to match.
Pure move, no logic change. The 3,275-line controller is now a 541-line core (state, overlay wiring, startDictation, cancel) plus eight DictationSessionController+*.swift extensions (RecordingStart, Stop, PasteBack, Persistence, Recovery, Presses, SessionCap, Telemetry) and DictationSessionDeliveryTypes.swift. Largest file is +Stop at 727 lines. Members another file needs went from private to internal; the rest stay private. The two statics moved into the one extension that uses them. The source-text assertions that read moved code out of DictationSessionController.swift are removed, not re-pinned: the held-back text wiring, the stop/start click counts, the stop-path checkpoint and empty-take wiring, the Quit preservation order, and the Try Again retry count. Pins on code that stayed in the core file still hold. Test-shape baseline shrunk to match.
…ude/cleanup-split
…p-split # Conflicts: # Tests/DictationStoppedAudioRecoveryTests.swift
…laude/cleanup-split # Conflicts: # Tests/DictationAudioRecoveryTests.swift # Tests/DictationStoppedAudioRecoveryTests.swift
…ude/cleanup-split
…ude/cleanup-split
… claude/cleanup-split
The split dropped about 20 source pins on DictationSessionController and MeetingSessionController. The code they guard is unchanged, just spread over +Area extension files. Two helpers now read a controller's core plus its extensions (or one part), and the pins are back: persist before the model wait, the Quit mark/wait/cancel order, the nine retry-marked startDictation calls, one start click and one stop click, held-back text, skipped-meeting outcomes, prompt outcome telemetry, retranscribe's People-in-the-room preference, and the capture-stop evidence order. TestHelpers' source-text baseline goes 8 -> 11 for the helpers; every other file is at or under its pre-split count.
|
Review verdict, applied in ad4173c. Two reviewers, findings merged: Fixed: dropped pins (both reviewers' #1/#2) and the DictationSounds comment (#2). Every dropped anchor still existed word for word in the split files, so they're back.
Mutation check: renaming Test-shape baseline: TestHelpers 8 → 11 for the two helpers. That's a baseline increase, so it needs your OK. Every other file is at or under its pre-split count (Analytics 11 → 10, DictationStartedTelemetry 2 → 1). Total is 358 vs 357 before the split. Skipped: pasteback smoke rule (#3/#1). The gap is real: Skipped: Not applied here, docs (second reviewer's #3). Checks: 🤖 Generated with Claude Code |
Stacked on #1949 (claude/cleanup-unpin). Merge that first.
This splits the 13 biggest hotspot files into smaller files in the same folders. It's a move, not a rewrite: each lane moved line ranges with a script and checked a line-multiset diff against the old file. The only differences are imports,
extensionwrappers, file headers, andprivatedropped where code in another file now needs it. No logic, strings, ordering, lock scopes, ornonisolated/@MainActormodifiers changed.Things worth knowing:
MeetingSessionController+State.swift.MeetingSessionController.swiftkeeps start/stop/signal verification because Notch island is the only dictation window #1946's UIAutomationSurfaceContractTests reads them by that path.readParakeetEngineSource()in Tests/TestHelpers.swift now joins the 8 engine files, and slice end markers moved to the next declaration in the same file. check-source-pins can't resolve the joined helper, so those pins only run in the fast tests.inputNodeor real-time callback body changed. Functions moved whole, so a Bluetooth headset as default input behaves as before.private); TranscriptionTaskManager keepstasksprivate behind three tiny helpers.Pins dropped instead of re-pinned (the controllers can't be built in the fast runner, so there's no behavior seam yet):
transcriptPersisted: true, the prompt-outcome event count and nil guard, retranscribe reading LocalSpeakerPreferences, capture-stop stash ordering.isRetry: true.drainRecordedSamplesForInference()pin Tests: replace source-text pins with behavior tests #1949 restored is kept, now on the joined engine source.Owner calls: accept the dropped pins above, and the MeetingSessionController class living in
+State.swift.Checks on the merged head: build-deps --force, build.sh --no-open, run-tests.sh (20,339 passed), run-integration-smoke.sh, run-e2e-smoke.sh, swift test (Core), swift test in TranscriptedMCP and TranscriptedQA, check.sh, check-source-pins, check-duplicate-declarations, check-build-source-lists, check-test-shape.
Not done yet: independent review of the full diff (use
git diff --color-moved=dimmed-zebra),bash scripts/ops/transcripted-qa-bench.sh --mode full, andbash check.sh hardwarewith AirPods as the default input. Hotspot rules want those before merge.Overlap: .agents/test-shape-baseline.json and scripts/entrypoints/run-tests.sh are also touched by #1946, #1942 and #1941. Whichever lands second re-runs the shrink / re-adds the list lines. .agents/test-matrix.yml still needs the five new clipboard files added to the pasteback smoke rule after #1945 lands.
🤖 Generated with Claude Code