Skip to content

Merge upstream LeanBitLab/LeanType v4.1.2 - #137

Merged
AsafMah merged 204 commits into
devfrom
merge/upstream-v4.1.2
Aug 20, 2026
Merged

Merge upstream LeanBitLab/LeanType v4.1.2#137
AsafMah merged 204 commits into
devfrom
merge/upstream-v4.1.2

Conversation

@AsafMah

@AsafMah AsafMah commented Aug 20, 2026

Copy link
Copy Markdown
Owner

Merges 200 upstream commits from LeanBitLab/LeanType, covering v4.0.9 → v4.1.2, pinned at tag SHA 8720abebd944eee38dcea0bee71bbd755fb51bb0.

Conflict decisions

File Resolution
app/build.gradle.kts ours — fork keeps 4200 / 0.2.0, never upstream's 4102 / 4.1.2
README.md, docs/FEATURES.md ours — fork-identity docs (our badges, two-thumb as namesake, our sponsor links)
docs/badges/*.svg ours, per the fork invariants
fastlane/.../changelogs/4100.txt ours — upstream reused the same versionCode; this is our 0.1.0 note
LatinIME.java both — fork's SwipeGestureEngine init/cancel plus upstream's sInstance tracking and voice-manager release
SettingsValues.java, strings.xml both — fork's flag-unknown-words + graduated-trust, plus upstream's personal-dictionary learning threshold
DictionaryFacilitatorImpl.kt both — fork's blacklist guard against auto-promotion, plus upstream's auto-capitalization decapitalize handling
ClipboardHistoryManager.kt ours — both define updateClipText with different signatures; ours returns the deleted entry so the caller can offer undo
SuggestionStripView.kt both, with upstream's recycled-view restore cancellation ordered before the fork's uncurated-word dialog so it can't be skipped by the early return
ClipboardHistoryView.kt theirs per hunk — upstream adds a clipboard edit mode; the fork side was only reformatting
MainSettingsScreen.kt @Preview arity updated to the merged 15-parameter signature

Two fork regressions found and fixed

Both came from automatic conflict resolution, and neither was caught by the compiler — only by the fork's own tests. This is the concrete argument for the "always audit Mergiraf resolutions" rule.

1. Whole-word backspace left partial words behind (5 failing tests)

Upstream 0cf92cf1b ("prevent single-click backspace from bulk deleting numeric sequences") split the end of the composing-word backspace branch on wasBatchMode. The fork's two-thumb whole-word delete also ends with no composing word but is not batch mode, so it fell into the new else — which calls deleteTextBeforeCursor, exactly the path its own comment warns against. That produced the "This is pretty cool""precool" corruption the fork had previously fixed.

Fixed with an explicit wholeWordDeleted flag so whole-word and batch both clear the composing span, while upstream's numeric-sequence fix still applies to the ordinary last-character path.

2. Custom layouts stopped restoring after symbol mode (1 failing test)

Upstream added lastCustomIndex = 0 when switching symbols → alphabet. This fork ships persistent custom layout slots meant to survive symbol mode, orientation changes and reloads (shipped in 0.1.0), and KeyboardStateTest asserts it. Dropped the upstream line.

Both inherited upstream defects are fixed — guards removed

HANDOFF §7 recorded two defects reproduced on a pristine upstream checkout and guarded with runTests skips. This merge fixes both, verified twice rather than assumed:

  • On the upstream check-out worktree re-pointed to v4.1.2, SubtypeTest passes (3 tests, 0 failures) — including subtypeStaysEnabledOnEdits.
  • In this merged tree, both subtypeStaysEnabledOnEdits and immediateRegexExpansionTriggersForSymbolPrefixedRegex pass.

Both runTests guards are removed. Worth calling out: those two tests were previously returning early on CI, so runTests was green on them for reasons unrelated to correctness. CI now genuinely covers them.

Verification

  • compileOfflineRunTestsKotlinpasses
  • :app:testOfflineRunTestsUnitTest (the CI variant) — 324 tests, 4 failed: exactly the documented Windows-only ParserTest baseline that passes on Linux CI. Unchanged from origin/dev.
  • :app:testOfflineDebugUnitTest (full suite, both sides on the same machine, minutes apart, 2026-08-20):
tests failures
origin/dev (6ac372de3) 320 12
this branch 324 5

Remaining on this branch: tapOnlyCombiningWordDoesNotShowAutospaceIndicatorWhenGestureGateEnabled and ParserTest ×4 (the same four the CI variant reports).

Seven tests stopped failing. Split by how confidently that can be attributed to this merge:

  • AttributablesubtypeStaysEnabledOnEdits and immediateRegexExpansionTriggersForSymbolPrefixedRegex (both independently confirmed fixed on a pristine upstream v4.1.2 checkout), and insertLetterIntoWordHangulFails (deterministic, no external inputs).
  • Plausible but unconfirmedStringUtilsTest ×2 and ParserTest > backgroundType. Both depend on bundled data/assets that this merge changes, so a real fix is likely, but it wasn't isolated.
  • Not attributableXLinkTest > otherLinks reaches Codeberg over the network and can flip with no code change at all. It is not counted as a fix.

Two corrections to earlier revisions of this description: it once quoted "4 failures → 1", which came from a run filtered to *InputLogicTest* + *SubtypeTest* and was never a whole-suite number; and it once claimed the merge "fixes seven", which overstates attribution for the three items above.

Failure names were diffed against an origin/dev baseline run, not pass counts.

Fork invariants re-verified after the merge: applicationId com.asafmah.leantypedual with its flavor suffixes; version 0.2.0/4200; INTERNET declared only in the standard and standardfull manifests; SwipeGestureEngine wired into LatinIME; the two-thumb module still registered in SettingsContainer; a single InitializationProvider.

Also fixed here

A latent test-harness bug: setText accepted a requireIdle parameter and then called handleMessages() without it, so reset()'s setText("", requireIdle = false) still asserted an idle queue. Harmless until this merge shifted JUnit's hash-based method ordering, after which it failed corpus - default mode char-by-char backspace during setup rather than in its own logic. (The same one-line fix appears independently in #134.)

Merge order

dev still carries the guards this PR removes, and #138's §7 documents them as gone — so merge this before #138. #134 and #136 both touch InputLogic.java and will want a small rebase afterwards.

Follow-ups

github-actions Bot and others added 30 commits August 6, 2026 02:42
LeanBitLab and others added 22 commits August 20, 2026 01:23
…ion self-hosted AI, and link LeanBitLab Android projects
Merges 200 upstream commits, pinned at tag SHA
8720abe, covering v4.0.9 through v4.1.2.

Conflict decisions:
- app/build.gradle.kts -> ours. Fork keeps versionCode 4200 / versionName
  0.2.0; never adopt upstream's 4102 / 4.1.2.
- README.md, docs/FEATURES.md -> ours. These are fork-identity documents
  (our badges, two-thumb as the namesake feature, our sponsor links);
  upstream's carry LeanBitLab branding.
- docs/badges/*.svg -> ours, per the fork invariants.
- fastlane changelogs/4100.txt -> ours. Upstream happened to reuse the same
  versionCode; this file is our 0.1.0 release note.
- LatinIME.java -> both sides. Kept the fork's SwipeGestureEngine
  initialize/cancelIndexing alongside upstream's new sInstance tracking and
  voice manager release.
- SettingsValues.java, strings.xml -> both sides. Fork's flag-unknown-words
  and graduated-trust settings plus upstream's personal-dictionary
  learning threshold.
- DictionaryFacilitatorImpl.kt -> both sides. Kept the fork's blacklist
  guard against auto-promotion and added upstream's auto-capitalization
  decapitalize handling for the word actually being added.
- ClipboardHistoryManager.kt -> ours. Both sides define updateClipText with
  different signatures; the fork's returns the deleted entry so the caller
  can offer undo.
- SuggestionStripView.kt -> both sides, with upstream's recycled-view
  restore cancellation ordered before the fork's uncurated-word dialog so
  it cannot be skipped by the early return.
- ClipboardHistoryView.kt -> theirs per hunk. Upstream adds a clipboard
  edit mode; the fork side was only reformatting.
- MainSettingsScreen.kt @Preview arity updated to the merged 15-parameter
  signature.

Fork invariants verified after the merge: applicationId
com.asafmah.leantypedual with its flavor suffixes, version 0.2.0/4200,
INTERNET declared only in the standard and standardfull manifests,
SwipeGestureEngine wired in LatinIME, the two-thumb module still
registered in SettingsContainer, and a single InitializationProvider.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a88bd77f-d993-44c5-9efc-c7124f0d825e
Both were introduced by automatic conflict resolution and were caught by
the fork's own tests, not by the compiler.

1. Whole-word backspace left partial words behind.

Upstream 0cf92cf ("prevent single-click backspace from bulk deleting
numeric sequences") split the end of the composing-word backspace branch
on wasBatchMode: batch mode clears the composing span with
commitText("", 1), everything else now calls finishComposingText()
followed by deleteTextBeforeCursor(1).

The fork's two-thumb whole-word delete also ends with no composing word,
but it is not batch mode, so it fell into the new else branch. That is
exactly the path its own comment warns against - deleteTextBeforeCursor
does not remove the composing region and deletes committed text before
it instead, which is the "This is pretty cool" -> "precool" corruption.
Five tests caught it.

Tracked with an explicit wholeWordDeleted flag so the whole-word and
batch paths both clear the span, while upstream's numeric-sequence fix
still applies to the ordinary last-character-removed path.

2. Custom layouts stopped restoring after symbol mode.

Upstream added `lastCustomIndex = 0` when switching from symbols back to
the alphabet. This fork ships persistent custom layout slots that are
meant to survive symbol mode, orientation changes and keyboard reloads
(0.1.0), and KeyboardStateTest asserts it. Dropped the upstream line.

Test suite is back to the documented Windows baseline of 4 ParserTest
failures, which pass on Linux CI.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a88bd77f-d993-44c5-9efc-c7124f0d825e
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: a88bd77f-d993-44c5-9efc-c7124f0d825e
AsafMah added a commit that referenced this pull request Aug 20, 2026
Section 5 was still headed "THE OPEN TASK - publish signed v0.2.0", which
is no longer true: v0.2.0 was published on 2026-08-20 with all four
signed APKs and is marked latest. The runner outage that blocked it
resolved on its own; Release run 31128748928 succeeded and produced the
draft.

Reframes section 5 from a blocker into the verified release procedure,
since the recipe itself is still what the next release should follow, and
keeps the outage signature so it is recognised rather than re-debugged.

Also refreshes the TL;DR table (v0.2.0 published, current dev head, the
four open PRs including #134, #136 and #137) and replaces section 12's
"publish v0.2.0" item with the work that is actually outstanding: device
verification of #134 and #137, re-pointing LeanType-check-upstream-main
to v4.1.2 to re-check the two guarded upstream defects, reporting the
emoji accelerated-delete bug upstream, and deciding the fate of the
unfinished worktrees whose commits exist on no remote.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a88bd77f-d993-44c5-9efc-c7124f0d825e
AsafMah added a commit that referenced this pull request Aug 20, 2026
…v4.1.2

Three statements written earlier in this PR went stale within the hour, so they
are corrected before merge rather than shipped as fresh staleness:

- Section 5 said the two runs stuck in queued could be cancelled; both have since
  been cancelled, so it now reads as history with the recovery command kept for a
  recurrence.
- Section 11 said check-upstream-main was intentionally pinned at v4.0.8 and
  should be re-pointed by whoever merges next. It has already been moved to
  v4.1.2 for PR #137, so it is now described as tracking the tag currently being
  integrated.
- Section 12 listed the re-pointing as an open item. The re-pointing is done; what
  remains is the re-check itself, which is in flight in #137 where the runTests
  guards live.

Also adds a forward pointer in section 7 so its v4.0.8 reproductions are not read
as the current state, and drops the stale cancel-the-zombies chore.

Verified against the API before editing: both runs report cancelled, and the
worktree HEAD resolves to tag v4.1.2.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a6e8f983-22c2-4f2f-aacd-5316a5924a4d
Both defects recorded in HANDOFF section 7 are fixed by this merge, so
their runTests skip guards are dead weight and were hiding two tests from
CI.

Verified twice rather than assumed:
- On a pristine upstream checkout re-pointed to v4.1.2,
  SubtypeTest > subtypeStaysEnabledOnEdits passes (3 tests, 0 failures).
- In this merged tree, both subtypeStaysEnabledOnEdits and
  immediateRegexExpansionTriggersForSymbolPrefixedRegex pass on the debug
  variant, where the guards do not apply anyway.

Also fixes a latent test-harness bug: setText accepted a requireIdle
parameter and then called handleMessages() without it, so reset()'s
setText("", requireIdle = false) still asserted an idle message queue.
That was harmless until this merge changed JUnit's hash-based method
ordering, after which a different test preceded
"corpus - default mode char-by-char backspace" and left a delayed message
behind, failing it during setup rather than in its own logic.

Debug-variant baseline moves from 4 failures on origin/dev
(tapOnlyCombiningWordDoesNotShowAutospaceIndicatorWhenGestureGateEnabled,
insertLetterIntoWordHangulFails, the regex expansion defect, and the
subtype defect) to 1 - only the long-standing autospace-indicator test
still fails. testOfflineRunTestsUnitTest remains at the documented
4 ParserTest failures that pass on Linux CI.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a88bd77f-d993-44c5-9efc-c7124f0d825e
AsafMah added a commit that referenced this pull request Aug 20, 2026
Section 7 claimed two tests fail on pristine upstream and are guarded with the
runTests skip. Upstream v4.1.2 fixes both, and PR #137 removed the guards, so the
section described a state that no longer exists.

Verified from the raw JUnit XML rather than taken on report:
- pristine v4.1.2 checkout, SubtypeTest = 3 tests / 0 failures,
  subtypeStaysEnabledOnEdits passing
- merged tree, InputLogicTest = 125 tests / 1 failure, with
  immediateRegexExpansionTriggersForSymbolPrefixedRegex passing
- commit e46454e on origin/merge/upstream-v4.1.2 removes exactly those two
  guards; the guards left elsewhere are unrelated (Linux-only ParserTest
  ordering, XLinkTest network, dictionary-dependent cases, emoji-data versioning)

Section 7 is kept as history rather than deleted, because the reusable lesson is
the technique: reproduce a merge failure on a pristine upstream checkout before
blaming your own merge. Neither defect needs reporting upstream now, so section
12 keeps only the emoji accelerated-delete report.

Section 6's known-failure list is split by baseline, since the merge moved it:
4 debug-variant failures on origin/dev versus 1 on the v4.1.2 branch, v4.1.2
having also fixed insertLetterIntoWordHangulFails. testOfflineRunTestsUnitTest is
unchanged at the 4 ParserTest failures that pass on Linux CI.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a6e8f983-22c2-4f2f-aacd-5316a5924a4d
@AsafMah
AsafMah merged commit ce586de into dev Aug 20, 2026
1 check passed
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.

2 participants