Skip to content

Release 1.1.67 fixes: integrate #1927 #1928 #1929 #1930 #1932 #1933 #1935 - #1934

Merged
r3dbars merged 17 commits into
mainfrom
claude/release-1.1.67-fixes
Sep 29, 2026
Merged

r3dbars merged 17 commits into
mainfrom
claude/release-1.1.67-fixes

Conversation

@r3dbars

@r3dbars r3dbars commented Sep 29, 2026

Copy link
Copy Markdown
Owner

Integration branch for today's 1.1.67 release, so CI runs once on the combined result instead of queuing each PR. Merge commits keep each PR's history (they'll show as merged).

Island focus/screen and the voiceprint off-main load (#1932, under review) join when ready.

🤖 Generated with Claude Code

Right Option fires hands-free dictation on press. When M, E, or an arrow
went down while it was held, the detector only sent .comboInterrupted if
CGEventSource.keyState(.combinedSessionState) said Option was down. Our
session tap consumes that Option flagsChanged, so the session state never
saw it, the check was always false, and every Option+M left a stray
dictation running until the next Option press pasted it.

HandsFreeModifierComboTracker now follows the held key from the tap's own
events with no key-state gate. It still ends on the key's own release and
on tap-disable reset, and also once no Option key is left down, so Right
Option let go under a held Left Option can't leave it armed.
Setup tells people Screen Memory "reads the window you're replying in",
but full-display capture could pull text from other visible windows and
apps, including apps outside the Writing app scope. Owner decision: read
only the window the user is typing in.

- New pure FocusedWindowCapturePolicy picks the capture target at capture
  time: the typing target's window, owned by the frontmost app, that app's
  frontmost normal window, not excluded (password managers included), in
  the app scope, and not contradicted by Accessibility's focused app.
  Anything unprovable refuses and nothing is captured.
- Full-display capture, CaptureKindPolicy and multi-window attribution are
  gone. The AX reader reads only the app's focused window when its frame
  matches the chosen one; no other-window search, no unmatched fallback.
- The service re-checks the app scope itself and drops held window text as
  soon as the user moves to another window or leaves the field.
- Lock screen, secure input, the master toggle and the any-visible-window
  exclusion gate are unchanged.
… call timeout behind dictation

- Once "Who was on this call?" naming ends (Done, Later, a newer review) or
  something covers it, the island hands key focus back to the app the person
  was in, without hiding and without activating Transcripted.
- A dictation opens the island on the display with the focused text field
  (one AX read per show, multi-display only), then the pointer's display,
  then main.
- The call prompt's timeout holds while it waits behind a dictation
  (CallPromptTimeoutClock), as it already did while hovered.
- Global mouse monitor hops with Task { @mainactor } instead of assumeIsolated.
- Clicking a dictation message's words no longer dismisses it.
- Pause for 1 hour is decided when a key is typed. The keyboard no longer
  captures while paused (it breaks the history segment), and the capture
  permit refuses during a pause, so text typed in a pause can't reach Save
  my writing or Personal History when the pause ends before delivery.
  WritingPausableIngest stays as the second layer.
- The completion stream's response waiter always wakes: finish() decides
  the waiter's outcome under the lock, and a response after finish is
  refused. The network side sits behind LlamaStreamNetwork so tests can
  interleave cancel and the response callback deterministically.
- The frontmost-window poll (1 Hz CGWindowListCopyWindowInfo) runs only
  with Autocomplete and Screen Memory on; the app-activation observer only
  with Autocomplete. Save-only users run neither.
- writing-diagnostics.log rolls to .1 at 4 MB.
- ModelManager records the launch check's fingerprint, taken from the same
  locked descriptor before and after the hash, so the first helper handoff
  skips a second full hash of the model.
- Launch reaps an orphaned llama helper once setup is done, whatever the
  Autocomplete switch says, off the main thread. Same rule as before: only
  our own binary, re-parented to launchd, sole listener.
MeetingSessionController.init runs on main in applicationDidFinishLaunching,
and it called SpeakerEmbedderFactory.makeEmbedder, which loaded ReDimNet2
(MLModel(contentsOf:), plus a GPU compile the first launch after an update)
right there. With ReDimNet2 the default, every launch froze the menubar for
that long.

makeEmbedder now loads nothing. It picks the model, and so the speaker
database, from model-file presence and returns Core's new
BackgroundLoadedSpeakerSegmentEmbedder, which knows the model's id, size and
thresholds up front and loads the real embedder on a utility queue the first
time something waits for it:

- DiarizationService awaits it during initialize() (the launch warmup), so
  "meeting models warm" still means the voiceprint is loaded, and again
  before re-embedding a meeting, so a meeting that races the load gets the
  right model's vectors.
- SpeakerVoiceprintMigration.run awaits it before moving anyone. The gate
  still closes at launch, so writers stay held through the load.

If the load fails, this launch keeps the model's own database and gets no
voiceprints (nothing 256-d ever reaches the 192-d file), the migration
fails with embedder_unavailable without writing the ledger, and
SpeakerEmbedderLoadFailureMemory makes the next launch on the same app
build and macOS version use WeSpeaker and speakers.sqlite, the old
fallback. A new build or macOS update tries the model again.
- A review confirmation now releases a held voiceprint-migration person in
  the same transaction, instead of waiting for the next launch's run.
  Unreadable held ledger rows are logged as a count.
- Separation step 1 folds a short voice only when it clears the model's
  microAbsorb bar; a voice with no fingerprint is never folded.
- The invite cap folds a voice only when it clears separationMerge, so a
  1:1 invite can't collapse a third person into the invitee.
- The separation provider reads the diarizer's active backend per meeting,
  so a Nemotron load failure gets pyannote's settings.
…eason

Review fixes for the focused-window change:
- A nil keyboard-focus answer from Accessibility now refuses
  (keyboardFocusUnknown). Without it a non-activating launcher's typing
  could read the frontmost window behind it.
- Each FocusedWindowCapturePolicy refusal logs a fixed reason string, and
  those plus no-target-window and target-changed are in the diagnostics
  allowlist, so skips no longer log as a redacted length.
- Stale full-display wording in comments and test titles; ledger records
  the CaptureTriggerPolicy doc change and the owner decision as a
  deviation from Tilde.
A dictation error with an action button never auto-dismisses and a model
download can run for minutes; holding the call prompt's timeout for all of
that would bring back a stale prompt much later. Each prompt now gets two
minutes off screen in total, then expires unanswered as before. Hover holds
stay uncapped.
@r3dbars r3dbars changed the title Release 1.1.67 fixes: integrate #1927 #1928 #1929 #1930 Release 1.1.67 fixes: integrate #1927 #1928 #1929 #1930 #1932 #1933 Sep 29, 2026
build-beta.sh now refuses to build without the Nemotron 3 diarizer and the
ReDimNet2 voiceprint model, and the Release Candidate runner has neither.
scripts/release/provision-release-models.sh fills the runner's FluidAudio
cache before build-beta, checking every file against pinned sha256s:

- Nemotron fast128 from FluidInference/nemotron-3-diarization-coreml at
  25a90f97 (the repo FluidAudio 0.17.0 downloads from), marker ga-2026-09-23.
- ReDimNet2 b4 slim from the models-redimnet2-b4-slim-v1 release asset.
- Either one from the previous release's app first when it matches the pins,
  so later releases reuse the same bytes.
@r3dbars r3dbars changed the title Release 1.1.67 fixes: integrate #1927 #1928 #1929 #1930 #1932 #1933 Release 1.1.67 fixes: integrate #1927 #1928 #1929 #1930 #1932 #1933 #1935 Sep 29, 2026
@r3dbars
r3dbars merged commit c7011b1 into main Sep 29, 2026
8 checks passed
@r3dbars
r3dbars deleted the claude/release-1.1.67-fixes branch September 29, 2026 21:03
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.

1 participant