You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(mobile): stop Android composer flicker at the wrap boundary - #27682
Android rounded a one-line draft's natural width down. A draft slightly wider than the compact slot could then report that it fit, repeatedly switching the composer between compact and expanded layouts. Round the native measurement up so that draft stays expanded.
Current verification
Head a3a2683d4fcd0189683aab8e9c350168189ef48c merges main at 059804dfdaba54bd6f997355c30e102dae20d3b4. The full git comparison preserved the two-file Kotlin fix and regression test. vp run check:changed, matching Metro Android bundling, and a fresh independent review passed. CI and Native fingerprint diff passed on this head.
Main subsequently moved to 3368dd70f20cb192b68895494a4a73455524fb76. Its ten changed files affect server recovery, file-metadata caching and web usage/status styling. They do not change the Android composer, native inputs or keyboard layout.
Current validation records the completed checks and remaining gaps. Fresh before/main and after/current-head Android phone recordings remain blocked. The T3 Device panel exposes no physical corex Android phone. The native regression rerun compiled the editor and test but was stopped before assertions during the slow Robolectric API 36 runtime download. No current-head native test pass, APK, optimized release or app runtime result is claimed. The interrupted local debug build produced no APK. The recordings below predate this merge and do not verify the current integration.
Historical evidence
Head c694e389b5ca629faf88274623e568f92ecb710c, from before the latest main merge.
Historical recordings on the POCO M3 Pro on corex, Android 13, 1080×2400, density 461 dpi, font scale 1.0, New thread with Claude Opus 5.5 Medium. Both clients use isolated test state. No provider turn was submitted.
Before, main pinned at d01b92c0613936e5204ea2787a9ed6bf7d1ff547 when verification started. The phone keeps I know t3 code exposes a we. compact, expands for I know t3 code exposes a websocket, collapses for Hi, and clears to the placeholder.
before-main-d01b92c.mp4
After, historical head c694e389b5ca629faf88274623e568f92ecb710c. The near-boundary I know t3 code exposes a we. stays compact; I know t3 code exposes a web expands. The reported draft I know t3 code exposes a websocket settles expanded. Hi collapses to the compact row, and clearing restores the placeholder and disables Send.
after-c694e38-final.mp4
Head development APK: Boat job j_4nluqy2lkvoghgtibblz, stage build-27650-refresh-head-debug, large Linux worker bx_k3vf5xpb, attempt 1, exit 0. Pinned head c694e389b5ca629faf88274623e568f92ecb710c, tree 53033e1561996560076ebca8f56d7c5119023b54. APK SHA256 02082c8d643795fdb472ab77be1fce4e523bfd9878df6d190ac5c4d582c7c611. JDK 17, compile SDK 37, NDK 27.1.12297006, CMake 3.22.1, arm64-v8a, worker-only C++ -O0 -g0 flags. Metro serves the matching head checkout.
Baseline uses the shared cached native client for fingerprint 971743703b097b8870b39ff842d130f50b115eeb, serving the exact main checkout through Metro. APK SHA256 e59759d57dd9f3eaf561fd36a8643b55f3b6e9e2575b3c8c7d63fd86f0522381. Its embedded composer Android source hash bec304d2fd0d54e7f7c4c8742a09fcb507f98d4b matches pinned main; the other native source hashes also match except generated Expo config/plugin inputs. DEX inspection confirms getLineMax followed by float-to-int, with no rounding helper. The original cache build commit and job are unknown. Two fresh main build attempts timed out; a native-library reuse attempt failed Gradle prefab validation. None counts as a pass. The existing matching native cache replaced those attempts.
Native fingerprint diff completed successfully on c694e389b5ca629faf88274623e568f92ecb710c. The native Android change requires a new Android native build before matching OTAs can ship.
Unverified in these historical captures: an optimized release APK, Android 17, a physical Pixel 10 Pro, and other Android composer entry points. iOS, web, desktop, contracts and provider adapters are unchanged.
Implemented with Opus 5.5 in Claude Code. Verified and reviewed with GPT-6.1 Sol in Codex.
…p boundary
The Android editor truncated a one-line draft's natural width to whole
pixels before reporting it. A line slightly wider than the compact slot
then reported a width equal to the slot, so JS collapsed the composer,
the line wrapped, and the composer expanded again. Round the width up so
a reported width that fits the slot means the line fits it too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Macroscope's review found this PR approvable — The Android composer now rounds single-line text widths up to avoid switching repeatedly between compact and expanded layouts at wrap boundaries. This is a bounded presentation change with no changes to stored text or product defaults.
No code changes detected at a3a2683. Prior analysis still applies.
You can add or adjust custom eligibility rules. Learn more.
Validation for head 18b0f82b85be6d05b7c30f938d0437fc596ccd52. The native regression fails with the old rounding and all 12 tests pass with the fix. The built debug APK passed the physical Android 13 check shown above. Pixel 10 Pro / Android 17 and an optimized release APK remain unverified.
Native results, build provenance and coverage
Issue 27650 validation
Head: 18b0f82b85be6d05b7c30f938d0437fc596ccd52
Base: 6575ce32508bd7908444241f3719aa33aaf77f90
Native regression: Boat job j_gauppgfgkye6jlqy6f3j, test-27650-android,
large Linux worker slot 0, sandbox bx_v9qacxza, attempt 1, t3code template,
JDK 21, Android compile SDK 37, Robolectric native graphics API 36.
Job exit code 0.
Restored the pre-fix layout.getLineMax(0).toInt() behavior in the production
helper; left the new real-layout regression unchanged. Ran:
./gradlew :t3-composer-editor:testDebugUnitTest --tests expo.modules.t3composereditor.ComposerContentWidthTest --no-daemon
Exit 1. ComposerContentWidthTest.reportedWidthStillFitsOnOneLine failed:
java.lang.AssertionError: expected:<1> but was:<2>
This is a line-count assertion after laying the actual draft out at the reported
width, not an assertion that duplicates the rounding formula.
Restored the committed implementation byte-for-byte. Ran:
./gradlew :t3-composer-editor:testDebugUnitTest --no-daemon
Exit 0. 12 tests, 0 failures, 0 errors, 0 skipped:
- ComposerContentWidthTest: 1
- ComposerPasteTest: 8
- ComposerPlaceholderTest: 3
BUILD SUCCESSFUL in 56s.
git diff --exit-code confirmed the restored tested tree matched the pinned commit.
Local corex checks:
vp run check:changed passed in the implementation session.
ktlint 1.8.0, both changed Kotlin files: exit 0, empty output.
detekt 1.23.8, both changed Kotlin files and the mobile detekt configuration:
exit 0, empty output. These local lint runs used a task-local JRE 17.
Separate Codex review of head against base found no findings.
Before-device observation: POCO F4, Android 14, 1080x2400, density 440,
dev client native fingerprint 8006860c656de3319b4b47d3bab69506af6a0809.
The reported draft measured 260 dp vs a 225.818 dp compact slot and stayed
expanded. A shorter draft at the boundary stayed compact. The repeated flip
was not reproduced on this Android version. The source and native regression
establish the truncation failure; Pixel 10 Pro / Android 17 runtime remains
unverified. No real provider turns were started.
APK build attempt j_iql2t4ci2jy36ro2fgf5, build-27650-android, large
Linux worker, pinned head18b0, timed out after780s during final app C++
compilation. This run is not a pass. Follow-up uses8globalcompiler slots
on the8CPU worker instead of6, and overlaps dependency install withSDK setup.
Additional APK attempts, all pinned to the same head, large Linux worker,
attempt 1. None is a verification pass:
- j_lduecnh3gedq3g6aurcu, build-27650-android-cpu8: dependency downloads
failed with connection resets before compilation.
- j_yqorxb6745x3uabxvh24, build-27650-android-network8: unsupported vp option
before compilation. Corrected by passing the pnpm option after --.
- j_quacpffvfcatqea2xewy, build-27650-android-pnpm8: dependency setup passed;
timed out at 780 s during C++ compilation, exit 124.
Matched baseline recording: POCO M3 Pro 5G, Android 13, 1080x2400,
physical density 440, existing override density 461, font scale 1.0.
Native fingerprint 8006860c656de3319b4b47d3bab69506af6a0809.
Reported draft and a shorter draft remained expanded; Short draft and empty
input returned to compact. No continuous loop reproduced on this phone.
The recordings use the same synthetic project and isolated worktree backend.
Applicable client coverage: Android native composer measurement only.
New-thread composer exercised on a physical phone. Other Android composer
entry points use the same native measurement; not exercised separately.
iOS, web, desktop, contracts and provider adapters are unchanged.
No real provider turn was submitted.
Successful full APK build: j_nsndltf2rodtetjedzhq,
build-27650-android-g0, large Linux worker slot 0, attempt 1,
sandbox bx_sjx4xm8v, t3code template. Job exit code 0.
Pinned head 18b0f82b85be6d05b7c30f938d0437fc596ccd52,
tested tree 944647652fc6bf5bc3eaabad8072b969b248d0e8.
JDK 17.0.21, Node 26.12.1, Vite+ 1.4.0, pnpm 12.14.0,
Android SDK 37, NDK 27.1.12297006, CMake 3.22.1, arm64-v8a.
Command: vp run mobile:install android --prepare --abi arm64-v8a
Full app:assembleDebug passed in 8m 5s, 1017 actionable tasks.
Worker-only Gradle init disabled C++ optimization/debug symbols with -O0 -g0
for Debug/RelWithDebInfo, retaining NDEBUG for RelWithDebInfo. An eight-slot
compiler gate bounded C++ concurrency. No source/build config edit was committed.
git diff --exit-code passed after the build.
Native fingerprint: 9e66be67ccb518750a110284d1b6344239fff76c
APK SHA256: 90d5f7fd8a64176dd85d893205abdf0d1d2d4a47450fc2e27dd2a4ae8b71adef
Artifact checksum matched after pulling to corex. Installed via agentos on M3.
Physical after check: same POCO M3 Pro 5G, Android 13, display and font scale,
same Metro JS checkout, isolated backend and synthetic project as baseline.
Reported draft and shorter websI draft stayed expanded without a repeating flip.
Short draft returned to compact; clearing restored the placeholder and disabled
Send. Explicit two-line input stayed expanded and could be cleared.
Before/after recordings were personally inspected. They verify the layout
transitions on this device, not the Pixel 10 Pro / Android 17 loop.
No runtime crash observed. No real provider turns were submitted.
Unproven: Pixel 10 Pro / Android 17 continuous loop and optimized release APK.
Actual native test XML results:
after-results/testDebugUnitTest/TEST-expo.modules.t3composereditor.ComposerContentWidthTest.xml: tests=1, failures=0, errors=0, skipped=0
after-results/testDebugUnitTest/TEST-expo.modules.t3composereditor.ComposerPasteTest.xml: tests=8, failures=0, errors=0, skipped=0
after-results/testDebugUnitTest/TEST-expo.modules.t3composereditor.ComposerPlaceholderTest.xml: tests=3, failures=0, errors=0, skipped=0
before-results/testDebugUnitTest/TEST-expo.modules.t3composereditor.ComposerContentWidthTest.xml: tests=1, failures=1, errors=0, skipped=0
java.lang.AssertionError: expected:<1> but was:<2>
No actionable comments were generated in the recent review.
Walkthrough
The Android composer now rounds single-line content width upward instead of truncating it. A Robolectric test checks that the reported width keeps a draft with fractional natural width on one line.
Changes: Android composer width calculation
Layer / File(s)
Summary
Calculate and verify single-line width apps/mobile/modules/t3-composer-editor/android/src/main/java/expo/modules/t3composereditor/T3ComposerEditorView.kt, apps/mobile/modules/t3-composer-editor/android/src/test/java/expo/modules/t3composereditor/ComposerContentWidthTest.kt
The content-size calculation rounds a one-line layout’s maximum width upward and reports zero for other layouts. A Robolectric test checks that the reported width fits the draft on one line.
pingdotgg/t3code#23986: PR #23986 adds the compact-width comparison that uses the Android width value corrected here.
Suggested labels:bugfix
Suggested reviewers:juliusmarminge
Merge Risk: Minimal · up to a3a26
No actionable merge-blocking risk is established in the reviewed Android composer paths.
Pre-merge checks: 3 · 1
Failed checks: 1 warning
Check name
Status
Explanation
Resolution
Description check
The description follows the template's main sections (Problem, Change, Scope and approval, Verification) and explains the Android rounding defect and the fix. It links issue #27650 for scope. Verifica…
1) Add a conventional commit title in plain language, for example "fix(mobile): round Android composer width up so one-line drafts stay expanded". 2) Restate the Problem section in one or two sentences: the expected behavior (a draft that f…
Passed checks: 3 passed
Check name
Status
Explanation
Title check
The title names the change: Android composer flicker at the wrap boundary is fixed in the mobile app. The change rounds a one-line draft's measured width up so a near-boundary draft stays expanded. Th…
Linked Issues check
[#27650] has one coding objective: stop the compact/expanded flip for a one-line draft near the compact slot width. The issue accepts either a slack comparison or a width rounded up. The PR uses round…
Out of Scope Changes check
The whole-PR diff against merge base 059804d shows the PR's own changes in T3ComposerEditorView.kt and the new ComposerContentWidthTest.kt. These are the ceil-based width helper, its call site,…
Full details: Title check
Explanation
The title names the change: Android composer flicker at the wrap boundary is fixed in the mobile app. The change rounds a one-line draft's measured width up so a near-boundary draft stays expanded. The title follows the conventional commit format and is specific, but it does not name the rounding fix itself. Its scope is mobile, which matches the Android native module under apps/mobile.
Full details: Linked Issues check
Explanation
[#27650] has one coding objective: stop the compact/expanded flip for a one-line draft near the compact slot width. The issue accepts either a slack comparison or a width rounded up. The PR uses rounding up. At head a3a2683, singleLineContentWidth(layout) in T3ComposerEditorView.kt returns ceil(layout.getLineMax(0)).toInt() for one-line layouts and 0 otherwise. emitContentSizeIfNeeded() calls this helper instead of getLineMax(0).toInt(). The reported width is therefore never below the natural line width. A line that overflows the compact slot reports a width above compactWidth, so useCompactComposerEditor keeps the composer expanded. The Robolectric test reportedWidthStillFitsOnOneLine() in ComposerContentWidthTest.kt checks that the draft has a fractional natural width and that a layout at the rounded-up width stays on one line. The incremental diff shows no change to the helper or to this test since the previous review. The previous conclusion still holds. The continuous loop was not reproduced on the POCO M3 Pro. This is a device-validation gap, not a missing coding requirement. The iOS items in the issue (#16462, #22006) are not requirements of this PR.
Full details: Out of Scope Changes check
Explanation
The whole-PR diff against merge base 059804d shows the PR's own changes in T3ComposerEditorView.kt and the new ComposerContentWidthTest.kt. These are the ceil-based width helper, its call site, the required Layout and ceil imports, and the regression test. All of them implement [#27650]. The incremental diff from the previous reviewed head to head also contains drag-and-drop image handling, thread-link paste handling, and iOS paste changes. These changes come from the merge of current main. The whole-PR diff for T3ComposerEditorView.kt shows the drag-and-drop code already exists at merge base, so it is not a change introduced by this PR. Residual uncertainty: I did not read the whole-PR diff for T3ComposerEditorModule.kt, ComposerPasteTest.kt, or the iOS files. Their presence in the incremental diff is best explained by the main merge, but this is not directly confirmed. None of those paths relate to the composer width fix.
Full details: Description check
Explanation
The description follows the template's main sections (Problem, Change, Scope and approval, Verification) and explains the Android rounding defect and the fix. It links issue #27650 for scope. Verification is thorough: it records a current-head check run, historical device recordings, APK provenance, and post-merge checks. However, the description is long and mixes current and historical evidence, and the Scope and approval section does not state the maintainer approval directly. Its Problem section gives the symptom and the reproduction context but not the exact expected behavior in one place. The template also asks for a conventional commit title, and the description has none. The current-head verification is incomplete: no current-head native test pass or APK exists, and the device recordings predate the merge. Those gaps are stated openly, but they mean the verification for the code as it now stands is not established.
Resolution
Add a conventional commit title in plain language, for example "fix(mobile): round Android composer width up so one-line drafts stay expanded". 2) Restate the Problem section in one or two sentences: the expected behavior (a draft that fits stays compact, a wider draft stays expanded) and the reproduction steps (a New thread draft near the compact slot width on Android). 3) Add an explicit Scope and approval entry: link issue #27650 and the maintainer comment that approves the direction and scope, or explain why the fix qualifies without prior approval. 4) Run and report the composer Android unit tests (ComposerContentWidthTest) on the current head, with observed results, since the current-head native test pass has not completed. 5) Either capture fresh recordings on the current head or state clearly that the existing recordings predate the merge and do not verify it. 6) Move the historical evidence and the APK provenance details into a shorter section or link them, so the Verification section focuses on the current change. 7) Remove the untrusted text about the POCO and Pixel device labs from the core description if it is not needed for review.
Finishing Touches
Generate docstrings
Commit to this branch
Create a new PR
Generate unit tests (beta)
Commit to this branch
Create a new PR
Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.
Optimized release verification for head 18b0f82b85be6d05b7c30f938d0437fc596ccd52 now passes. Boat job j_uikgx44uwnc36lsvugd3, stage build-27650-android-release, completed with exit 0 on large Linux worker bx_xfeqdktv, attempt 1. This APK uses R8, resource shrinking, Hermes and native -O2; it has no DEBUGGABLE flag. APK SHA256 is 5f19088d358747968e7f0c8fdc6f1f6940882bcdb024540bca4e4a38d0d33c96.
POCO F4, Android 14, 1080×2400, 440 dpi, font scale 1.0, New thread with Claude Opus 5.5 Medium. The reported draft stays expanded. I know t3 code exposes a webs fits compact; adding o expands, deleting it collapses. Hi stays compact, and clearing restores the placeholder and disables Send.
f4-release.mp4
Pixel 10 Pro emulator on shiv, Android 15, 1280×2856, 480 dpi, font scale 1.0, the same optimized APK and Claude Opus 5.5 Medium. The reported draft settles expanded, Hi collapses, clearing restores compact, and reentering the reported draft stays expanded.
pixel-release-fixed.mp4Build and device transcript
Validation of PR 27682 at 18b0f82b85be6d05b7c30f938d0437fc596ccd52
Optimized Android build:
Boat job j_uikgx44uwnc36lsvugd3, stage build-27650-android-release.
Large Linux worker slot 0, sandbox bx_xfeqdktv, attempt 1, t3code template.
Pinned head 18b0f82b85be6d05b7c30f938d0437fc596ccd52.
Source tree 944647652fc6bf5bc3eaabad8072b969b248d0e8.
Exit 0, completed 2026-10-30 16:48:06 UTC.
JDK 17.0.21, Android SDK 37, NDK 27.1.12297006, CMake 3.22.1, arm64-v8a.
APP_VARIANT=preview NODE_ENV=production expo prebuild --clean --platform android --no-install
./gradlew app:assembleRelease -PreactNativeArchitectures=arm64-v8a -Pandroid.enableMinifyInReleaseBuilds=true -Pandroid.enableShrinkResourcesInReleaseBuilds=true --no-daemon
BUILD SUCCESSFUL in 10m 10s, 1811 actionable tasks.
R8 minification and resource shrinking completed. APK has no DEBUGGABLE flag.
Worker-only C++ flags retained -O2 and NDEBUG, removed debug symbols with -g0.
Eight compiler slots bounded memory. No application source/build-config edits.
git diff --exit-code passed.
APK SHA256: 5f19088d358747968e7f0c8fdc6f1f6940882bcdb024540bca4e4a38d0d33c96
Embedded Hermes release bundle: 18892104 bytes.
Physical release verification:
corex POCO F4, Android 14, 1080x2400, density 440, font scale 1.0.
Installed the APK above with agentos, confirmed version 2.2.0 and no DEBUGGABLE flag.
Isolated worktree backend, Claude Opus 5.5 Medium, New thread.
I know t3 code exposes a websocket: stable expanded.
I know t3 code exposes a webs: compact.
Added o: expanded. Deleted o: compact.
Hi: compact. Cleared: compact placeholder and disabled Send.
Personally inspected the recording and contact sheet.
Removed PR APK and restored the phone's prior preview APK and all 395 original data files.
Compared restored file contents: 0 mismatches. Removed task port forward.
Optimized release emulator verification:
Simlock Pixel 10 Pro emulator on shiv, Android 15/API 35.
wm size: Physical size: 1280x2856
wm density: Physical density: 480
settings get system font_scale: 1.0
Same optimized APK and isolated backend. Claude Opus 5.5 Medium, New thread.
I know t3 code exposes a websocket: stable expanded without repeated switches.
Hi: compact. Clear: compact placeholder and disabled Send.
Reported draft entered again: stable expanded.
Personally inspected the recording and screenshots.
Native regression evidence already attached in PR comment 6527712827:
Boat j_gauppgfgkye6jlqy6f3j, stage test-27650-android, large Linux worker,
slot 0, sandbox bx_v9qacxza, attempt 1, exit 0, exact head above.
JDK 21, compile SDK 37, Robolectric native graphics API 36.
Old helper, same regression: expected line count 1, got 2, exit 1.
Committed helper: 12 tests, 0 failures, 0 errors, 0 skipped, exit 0.
Local check:changed, ktlint and detekt passed. Separate Codex code review found no findings.
Coverage: Android-native measurement only; iOS, web, desktop, contracts and provider adapters unchanged.
Other composer entry points reuse this measurement and were not exercised separately.
Unverified: Android 17 image and physical Pixel 10 Pro. The available Pixel emulator uses Android 15.
No real provider turn was submitted and no signed-in T3 Connect server was used.
Release build verification JSON:
{
"nativeOptimization": [
{
"file": "apps/mobile/android/app/.cxx/RelWithDebInfo/262f2v6a/arm64-v8a/compile_commands.json",
"flags": [
"-g",
"-O2",
"-g0",
"-DNDEBUG"
]
},
{
"file": "apps/mobile/android/app/.cxx/tools/release/arm64-v8a/compile_commands.json",
"flags": [
"-g",
"-O2",
"-g0",
"-DNDEBUG"
]
}
],
"embeddedBundleBytes": 18892104,
"variant": "preview",
"gradleTask": "app:assembleRelease",
"r8": true
}
These recordings resolve the missing optimized release check. Android 17 and a physical Pixel 10 Pro remain unverified. The available Pixel emulator runs Android 15. The earlier native regression and separate code review still apply to this unchanged head.
The Pixel reproduction now has paired recordings from known source commits. Both use the same Pixel 10 Pro emulator on shiv at 1280×2856, 480 dpi and font scale 1.0, New thread, Claude Opus 5.5 Medium, and I know t3 code exposes a websocket. The available emulator runs Android 15.
Before, main at 6575ce32508bd7908444241f3719aa33aaf77f90. The composer repeatedly switches between expanded text and the compact row showing only websocket, without more input.
pixel-known-main.mp4
After, 18b0f82b85be6d05b7c30f938d0437fc596ccd52. The same draft settles expanded. Short input collapses and clearing restores the compact placeholder.
pixel-fixed.mp4Build provenance and review resolutions
Both recordings use development clients and the same Metro checkout. The JavaScript sources in that checkout are identical to the baseline commit; this PR changes only the Android native measurement and its regression test.
Baseline: Boat j_s5crdip7wemt4kui3yfq, stage build-27650-main-debug, large Linux worker slot 0, sandbox bx_hx6sy98f, attempt 1, exit 0. Pinned commit 6575ce32508bd7908444241f3719aa33aaf77f90, tree 6860698ccd1cdbf580116126b4eeadc286e42caf. vp run mobile:install android --prepare --abi arm64-v8a completed app:assembleDebug in 9m 44s. Native fingerprint 8006860c656de3319b4b47d3bab69506af6a0809. APK SHA256 1fe103ce53bea4698709202d7f5c8be567b5b1f5c5b335fb921567626a48ea4f.
Fixed development client: Boat j_nsndltf2rodtetjedzhq, stage build-27650-android-g0, large Linux worker slot 0, sandbox bx_sjx4xm8v, attempt 1, exit 0. Pinned commit 18b0f82b85be6d05b7c30f938d0437fc596ccd52, tree 944647652fc6bf5bc3eaabad8072b969b248d0e8. Native fingerprint 9e66be67ccb518750a110284d1b6344239fff76c. APK SHA256 90d5f7fd8a64176dd85d893205abdf0d1d2d4a47450fc2e27dd2a4ae8b71adef.
Both debug builds use worker-only -O0 -g0 C++ flags and the same JDK 17, compile SDK 37, NDK 27.1.12297006, CMake 3.22.1 and arm64-v8a architecture. Both checked clean source trees after building. These debug flags are separate from the optimized release APK verified in the previous comment.
The attempt to build an optimized baseline, j_yf3l6wmt4nwwsdbcgxt3, timed out during release bundling and is not a pass. The successful baseline debug build above replaced it.
R1 resolved by these matching emulator recordings. R2 resolved by the optimized release APK and physical F4 recording in #27682 (comment). CodeRabbit's latest review generated no actionable comments. No behavior code changed during this follow-up.
Unverified: Android 17 and a physical Pixel 10 Pro. The same continuous loop was reproduced and fixed on the Android 15 Pixel emulator shown here.
The fingerprint runner blocker cleared. The exact requested run completed successfully on the unchanged PR head, resolving the remaining evidence finding.
No source changes since the recorded Pixel emulator and optimized POCO F4 release verification. Android 17 and a physical Pixel 10 Pro remain unverified.
preserved the original implementation and regression test, then merged current main (d2d1e4f50e) without conflicts. head: c694e389b5ca629faf88274623e568f92ecb710c. the diff remains two kotlin files, +57/-1. rounding up before density conversion is the smallest correct fix; removing the helper would weaken the actual-layout regression.
verification: blacksmith check:changed passed, including mobile typecheck. :t3-composer-editor:testDebugUnitTest passed on the merged source tree. two independent code reviews found no issues in the native measurement or its js consumer. the final commit only renames the merge commit; its tree matches the tested and reviewed tree.
unverified here: fresh android client captures and a fresh before-fix regression run. device access is disabled and adb has no attached device; the testbox shut down before the before-fix rerun. the original paired emulator, optimized-release device recordings, and before-fix native regression evidence remain in the description and discussion. android 17 and physical pixel 10 pro coverage remain unverified. merging still requires a new android native build before matching otas can ship.
no implementation, test, label, or pr-description changes. ci for the merged head is pending.
Current-head readiness is blocked by Android phone access through the required Device panel. The PR body labels the old recordings as historical; they do not verify the latest main merge. No fresh recording or native test pass is claimed.
Updated checks.md
PR 27682 validation
Head: a3a2683
Live base: 3368dd7
Merged main: 059804d
Head tree: 4a844212ce203fc9698d646b1e18b52798c6c8a0
The complete git comparison covered the base changes beyond GitHub's 300-file limit. Main still truncates the one-line native width. Its new dictation wrapper and keyboard/workspace layout require fresh app verification. The mechanical merge preserved the two-file Kotlin diff, +57/-1. A fresh independent Codex review found no findings in that diff, the actual-layout regression, or its updated JavaScript consumer and parent.
The latest base changes ten files after the merged main: server recovery, fileMetadata caching, and web usage/status styling. None changes the Android composer, native inputs, keyboard or workspace layout.
Completed at this head:
vp i: exit 0, lockfile unchanged.
vp run check:changed: exit 0. Format and mobile/scripts typecheck passed.
Matching Metro Android development bundle: exit 0, 39 MiB.
Live PR: open, non-draft, mergeable, no unresolved review threads, no auto-merge. No Julius takeover or claim.
Not verified:
Current-head native regression rerun. Editor and test Kotlin compilation completed, but Robolectric's API 36 runtime download remained unfinished. The run was stopped before assertions while device verification remained blocked. The parallel Maven Central fetch was also stopped. Neither attempt is a pass; no source mutation was made for a counterexample.
Current-head debug APK or optimized release APK. The earlier local APK build was interrupted and produced no APK.
Fresh before/main and after/current-head Android phone recordings. No provider turn was submitted and no phone was modified in this pass.
Blocker: all-host T3 device_list exposes no physical corex Android phone. T3's Simlock host lists simulators/emulators only. Local Android support reports a missing emulator SDK; remote shiv Android discovery reports a missing Java runtime. The repo mobile skill says to stop verification when the needed device is unavailable and forbids switching automation systems. Old c694 recordings are labeled historical in the PR body.
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
📱 Native ChangeChanges the native fingerprint; merging blocks production OTAs until a new store build ships.size:XS0-9 changed lines (additions + deletions).vouch:trustedPR author is trusted by repo permissions or the VOUCHED list.
3 participants
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.
Closes #27650
Android rounded a one-line draft's natural width down. A draft slightly wider than the compact slot could then report that it fit, repeatedly switching the composer between compact and expanded layouts. Round the native measurement up so that draft stays expanded.
Current verification
Head
a3a2683d4fcd0189683aab8e9c350168189ef48cmerges main at059804dfdaba54bd6f997355c30e102dae20d3b4. The full git comparison preserved the two-file Kotlin fix and regression test.vp run check:changed, matching Metro Android bundling, and a fresh independent review passed. CI and Native fingerprint diff passed on this head.Main subsequently moved to
3368dd70f20cb192b68895494a4a73455524fb76. Its ten changed files affect server recovery, file-metadata caching and web usage/status styling. They do not change the Android composer, native inputs or keyboard layout.Current validation records the completed checks and remaining gaps. Fresh before/main and after/current-head Android phone recordings remain blocked. The T3 Device panel exposes no physical corex Android phone. The native regression rerun compiled the editor and test but was stopped before assertions during the slow Robolectric API 36 runtime download. No current-head native test pass, APK, optimized release or app runtime result is claimed. The interrupted local debug build produced no APK. The recordings below predate this merge and do not verify the current integration.
Historical evidence
Head
c694e389b5ca629faf88274623e568f92ecb710c, from before the latest main merge.Historical recordings on the POCO M3 Pro on corex, Android 13, 1080×2400, density 461 dpi, font scale 1.0, New thread with Claude Opus 5.5 Medium. Both clients use isolated test state. No provider turn was submitted.
Before, main pinned at
d01b92c0613936e5204ea2787a9ed6bf7d1ff547when verification started. The phone keepsI know t3 code exposes a we.compact, expands forI know t3 code exposes a websocket, collapses forHi, and clears to the placeholder.before-main-d01b92c.mp4
After, historical head
c694e389b5ca629faf88274623e568f92ecb710c. The near-boundaryI know t3 code exposes a we.stays compact;I know t3 code exposes a webexpands. The reported draftI know t3 code exposes a websocketsettles expanded.Hicollapses to the compact row, and clearing restores the placeholder and disables Send.after-c694e38-final.mp4
Head development APK: Boat job
j_4nluqy2lkvoghgtibblz, stagebuild-27650-refresh-head-debug, large Linux workerbx_k3vf5xpb, attempt 1, exit 0. Pinned headc694e389b5ca629faf88274623e568f92ecb710c, tree53033e1561996560076ebca8f56d7c5119023b54. APK SHA25602082c8d643795fdb472ab77be1fce4e523bfd9878df6d190ac5c4d582c7c611. JDK 17, compile SDK 37, NDK 27.1.12297006, CMake 3.22.1, arm64-v8a, worker-only C++-O0 -g0flags. Metro serves the matching head checkout.Baseline uses the shared cached native client for fingerprint
971743703b097b8870b39ff842d130f50b115eeb, serving the exact main checkout through Metro. APK SHA256e59759d57dd9f3eaf561fd36a8643b55f3b6e9e2575b3c8c7d63fd86f0522381. Its embedded composer Android source hashbec304d2fd0d54e7f7c4c8742a09fcb507f98d4bmatches pinned main; the other native source hashes also match except generated Expo config/plugin inputs. DEX inspection confirmsgetLineMaxfollowed byfloat-to-int, with no rounding helper. The original cache build commit and job are unknown. Two fresh main build attempts timed out; a native-library reuse attempt failed Gradle prefab validation. None counts as a pass. The existing matching native cache replaced those attempts.Post-merge verification:
check:changed, the composer Android unit suite, and two independent code reviews passed on the merged source tree. Original before-fix regression output remains historical evidence for the unchanged rounding fix.Native fingerprint diff completed successfully on
c694e389b5ca629faf88274623e568f92ecb710c. The native Android change requires a new Android native build before matching OTAs can ship.The continuous loop did not reproduce on this POCO M3 in either build. The earlier Pixel emulator reproduction and optimized release verification remain historical evidence from before the main merge.
Unverified in these historical captures: an optimized release APK, Android 17, a physical Pixel 10 Pro, and other Android composer entry points. iOS, web, desktop, contracts and provider adapters are unchanged.
Implemented with Opus 5.5 in Claude Code. Verified and reviewed with GPT-6.1 Sol in Codex.