Skip to content

feat: on-device llm rewrite pass for dictated takes - #28

Merged
joshuagruenstein merged 3 commits into
mainfrom
feat-rewrite-pass
Jul 12, 2026
Merged

feat: on-device llm rewrite pass for dictated takes#28
joshuagruenstein merged 3 commits into
mainfrom
feat-rewrite-pass

Conversation

@joshuagruenstein

Copy link
Copy Markdown
Member

What

Optional post-dictation polish using Apple's on-device Foundation model (Apple Intelligence, macOS 26+), configured via a new literate [rewrite] section: templated switches (removeFillers, fixPunctuation, fixGrammar, correctVocabulary, technicalFormatting) plus one freeform customInstructions. Off by default.

Design

  • Mechanical vs judgment split: um/uh/er stripping is a deterministic regex (works even without Apple Intelligence); the model only does punctuation, dedup, vocabulary-aware mis-transcription repair, and symbol-speak.
  • Transcript is data, not conversation: sent wrapped in <transcript> tags with instructions that questions/requests inside are things the speaker said. Without this, the 3B model answers meta-dictation instead of editing it.
  • Acceptability gate: rejects empty/ballooned output, low word retention (answers/refusals), and silent profanity censorship (every profane token in must come out, same count — the model's safety training otherwise swaps swears for tame verbs). Rejection degrades to the filler-stripped text; the user's words are never at risk.
  • Apply: single prefix-cut keystroke edit (delete back to the first changed character, retype the rest). Backspaces physically cannot preserve a common suffix, so no other diff shape is valid — pinned by regression tests that simulate field semantics, including grapheme cases.
  • Cancellation: new squeeze, erase, send, or app switch invalidates a pending rewrite (generation counter + take-identity + frontmost-app checks). Blue menu bar dot while the model runs.
  • Stage-by-stage logging (in → stripped → model out → gate verdict → applied edit) for future debugging.

Prompt was tuned across four eval rounds against 50 real dictations via the new --rewrite-eval harness (runs the production pipeline against a sample file): final round has zero gate rejections, ~1.7s average latency.

Also carries two live-verified UX fixes: sequenced permission prompts (mic → accessibility, so the second dialog isn't buried) and no OK button on in-progress cards.

Testing

  • 283 assertions green (swift run tingle-tests), including new suites for filler strip, gate, prompt assembly, profanity backstop, and the edit/apply path
  • Payload + version tooling tests green
  • Live-tested by Josh on the dev build (rewrite quality, blue dot, permission sequencing, progress cards)

🤖 Generated with Claude Code

joshuagruenstein and others added 3 commits July 12, 2026 02:10
After a take finalizes, Apple's on-device Foundation model polishes it
in place: punctuation, repeated-word dedup, vocabulary-aware fixes,
optional symbol-speak. Deterministic regex handles fillers; the model
only does judgment work. Transcript goes in as delimited data (never a
message); an acceptability gate rejects answers, refusals, and silent
profanity censorship, degrading to the filler-stripped text. Applied as
a prefix-cut keystroke edit ~1-3s after release; cancelled by squeeze/
erase/send/app switch; blue menu dot while the model runs. Off by
default ([rewrite] enabled in config).

Also: permission prompts now sequence (mic then accessibility) so the
second dialog isn't buried, and live progress cards drop their OK
button until done.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@joshuagruenstein
joshuagruenstein merged commit e8a5d84 into main Jul 12, 2026
2 checks passed
@joshuagruenstein
joshuagruenstein deleted the feat-rewrite-pass branch July 12, 2026 06:22
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