Repository navigation
Improve layout reliability, personal exceptions, and benchmark coverage - #22
Merged
Merged
Conversation
…o one Cyrillic layout Ukrainian <-> Russian conversion is removed entirely, along with its setting. Latin text now converts only to the active or last-used Cyrillic layout, so typing on the Ukrainian layout can no longer produce Russian corrections.
Apple's layouts list every language their script can write, so "Ukrainian" also declares ru. Reading the whole list made it a Ukrainian + Russian hybrid: Russian words counted as valid on it, and "фил" (ask) was left uncorrected because it is a Russian word. Third-party layouts keep every language they declare.
… the layout
The layout cannot change in the middle of an uninterrupted run of typing, so
the detector now keeps a journal of the run instead of one deferred short word.
When a word is corrected, the correction reaches back over the earlier words
that also read as valid words in the target layout:
- words valid in both layouts are reachable at any length and no longer dropped
when the next word is short ("філ me more" -> "ask me more")
- a word typed after two or more untracked backspaces is recorded, never judged
on its own, and fixed with the rest of the run
- a word valid in both layouts stays as typed when the word before it is valid
only as typed ("лист від google" no longer becomes "dbl google")
- the sweep never crosses Enter or a word that is valid in neither layout
The state machine owns the run, so the detector can no longer count a word
that was reopened with backspace, or skip a second space, when sizing the
deletion.
Add implementation plans for dynamic layout mapping, personal exceptions, and comparative false-positive benchmark. Set up PROGRESS.md tracking for plan execution and ignore benchmark results in .gitignore. Plan-Item: 0
Add LayoutBenchmark executable target supporting layout table export and corpus validation. Freeze 22 layout tables in Benchmarks/layout-tables/v1 for 11 standard keyboard layouts. Generate the 200-trial seed corpus in Benchmarks/layout-corpus/v1 (100 development, 100 holdout) with disjoint groups and SHA-256 manifest integrity verification. Plan-Item: 03.1
…ine drain seam Extract DetectionRequestAssembly into Core with DetectionConfiguration, assembleDetectionRequest, and evaluateDetection. Add drainPipeline multi-queue drain seam to InputEngine and add test coverage. Implement SwitchFixAdapter replaying synchronously on InputStateMachine and LayoutDetector with virtual editor, Scorer with Wilson 95% intervals, and run/summarize subcommands. Plan-Item: 03.2
Implement SelfChecks in LayoutBenchmark with 36 assertions testing Wilson score intervals, zero-attempt precision null handling, fake control adapters (always-preserve, always-replace, wrong-repair, and known-good), schema/split validation error detection, UTF-16 vs grapheme clusters, replay delete/reset, suffix mismatch guards, source switch dynamic rendering, and transient damage checkpoints. Add GitHub Actions CI workflow at .github/workflows/layout-benchmark.yml on macos-15. Plan-Item: 03.3
Add record-baseline subcommand to LayoutBenchmark and record the frozen
SwitchFix baseline v1 across all 200 trials (development, holdout, combined)
in Benchmarks/baselines/v1/baseline.{json,md}.
Combined baseline achieves 90.0% recall (36/40), 90.0% precision (36/40),
0.00% text-damage FP (0/160, 95% Wilson CI [0.0%, 2.3%]), 0.00% layout-only
FP (0/160), and 100% preservation (160/160 TN). The 4 false negatives in
EN -> UK are confirmed to be caused by static Ukrainian variant mapping
ambiguities, which will be addressed in Plan 01.
Plan-Item: 03.4
Implement PersonalExceptionsPolicy with NFC normalization, locale-independent lowercasing, apostrophe normalization (ASCII ', U+2019, U+02BC), 1-64 character and <=256 byte limits, Unicode letter requirement, and matching key derivation based on detector token-splitting rules. Implement PersonalExceptionsStore with UserDefaults persistence under SwitchFix_personalExceptions_v1, schema versioning, 1,000-entry capacity limit, and envelope validation. Add 79 unit tests in TestRunner. Plan-Item: 02.1
…uration invalidation Introduce CorrectionTrigger (.automaticBoundary, .hotkey, .layoutSwitch) carried explicitly in DetectionRequest and CorrectionPlan. Add invalidateCorrectionConfiguration() to CaptureStateStore to bump epoch on configuration updates. Wire personal exceptions into LayoutDetector for automatic current word suppression, confidence reset, and journal backward sweep barriers on typed and display text. Add engine safeguards for exactDetection test seams and add regression tests in TestRunner and InputPipelineTestRunner. Plan-Item: 02.2
…d SettingsView Expose PersonalExceptionsStore methods and policy snapshots on PreferencesManager, posting .preferencesDidChange on changes. Wire AppDelegate to push personal exceptions to InputEngine on startup and on preference updates. Add Personal Exceptions section to SettingsView with word list, count/capacity indicator, Add field with validation messages, and Remove Selected button. Add pipeline test for in-flight correction cancellation upon exception modification. Plan-Item: 02.3
Stop logging the protected typed word (SwitchFixLog is public). Derive exception keys from the detector's own tokenizers instead of a copy. Republish exceptions only when the set changes, so unrelated preference edits no longer invalidate corrections or reset detector context. Keep the next word after a configuration change: only a word in progress is skipped to its boundary. Carry the real trigger on selected-text corrections, reject a lone combining mark as a letter, and report an unreadable or partly invalid stored list in Settings. Add the detector, store and pipeline cases the first slices left untested; the display-barrier and confidence-reset mutations that previously passed now fail the suite. Plan-Item: R1
Configure each trial's sources, Ukrainian variant and active-source layouts with the app's own discovery and AppDelegate rules instead of hardcoded standard variants, classify keys like KeyboardMonitor, and plan edits with the engine's shared planCorrectionEdit. Stop hiding failures: suffix mismatches, missing tables, errors and missing results are now reported, scored as failures or coverage loss, and checkpoints and allowed actions are scored. Self-checks now exercise the real scorer, validator, editor, renderer and adapter and cross-check traces against InputEngine. The validator verifies manifests, carets and exact tables and reports label conflicts; the generator is versioned and byte-deterministic; baselines record measured metadata; run --baseline gates per trial; CI no longer ignores pipeline failures. Plan-Item: R2
v1 typed four inputs identically under contradictory labels, leaked "apple" across splits as a reversed mapping, and had no negative whose intended token is a word in the other layout. v2 replaces the five affected holdout trials under new IDs and adds ten cross-layout collision preserves per split, five typed on ABC and five on Ukrainian. Generated byte-deterministically by 5daf653; passes validate --strict with no warnings. v1 stays frozen. Plan-Item: R3
Baseline v1 measured a harness misconfiguration (standard Ukrainian variant for a legacy source, non-app key classification). Record v2 from a clean worktree at c22be93 on corpus v2 (reference) and v1 (comparison), with measured environment and runner results, and mark v1 superseded. CI validates v2 strictly and gates the development run per trial against baseline v2; the execution instructions point later items at corpus v2 and baseline v2. Plan-Item: R4
Invalidate stale detection work while publishing the new epoch before manual layout-switch corrections. Preserve benchmark quality denominators, separate layout-only checkpoint errors, reject unreachable exceptions and unsupported carets, batch exception deletion, and reject cross-layer baseline comparisons. Tested: release build; TestRunner 459/459; InputPipelineTestRunner 1016/1016; benchmark self-check 112/112; v1/v2 validation and development baseline gates; cross-layer gate rejection Scope-risk: narrow
Member
Author
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Codex Review: Didn't find any major issues. 🚀 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
This was referenced Oct 20, 2026
…rovements Publish curated release notes and highlight personal exceptions, phrase correction, and safer layout pairing. Tested: 474 core checks, 1016 pipeline checks, 123 benchmark self-checks, ad-hoc app build
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes
Validation
Known issues
Issues #14 (newer Swift bundle packaging), #15 (Globe focus race), and #16 (modifier-only shortcuts) remain open and are listed in the release notes.