Repository navigation
Phase 8: release hardening - #10
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ck in CI Release signing reads SIGNING_* environment variables only (DETECT pattern); without them the release stays unsigned, a wrong path or a missing password fails the build. tools/build_release.sh takes the password from the macOS Keychain and builds the APK + AAB without the configuration cache. tools/check_release_apk.py reads the R8 dex through mapping.txt: not debuggable, no ScrollMeter class calls android.util.Log, no debug recording literals. CI builds assembleRelease and runs the check. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…vice (ADR-033) Measured on the API 28 emulator: with only ScrollMeter bound, no scroll event of our own test list arrived (18/18 runs) and Settings got through only sometimes. AOSP 9 forwards TYPE_VIEW_SCROLLED only from the active window, which moves only on TYPE_WINDOW_STATE_CHANGED — and apps send that only when a bound service asks for it. Android 10 adds it to every non-cache service's relevant types (without delivering it), so API 29+ works within the hard rules. UsageAccessChecker drops its pre-29 branch. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…DR-033, ADR-034) With minSdk 29 R8 merged androidx.profileinstaller.ProfileInstaller$2 (which logs) into CalibrationRepository$Companion, so a check that attributes Log calls to classes cannot tell ours from library code. The release now declares android.util.Log side-effect free (isLoggable false) and check_release_apk.py requires no Log invocation anywhere in the dex. device_accuracy.py no longer re-reads a stale UI dump when uiautomator fails. ADR-033 (minSdk 29), ADR-034 (release). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ne's (ADR-035) Android 13+ applies the per-app language to activity contexts only. The erase toast (application scope) and AndroidNotificationPoster built their text from the application context, so a Czech app on an English phone said "All measured data is deleted." (API 33 and 36 emulators) and would have notified in English. Context.inAppLanguage() applies LocaleManager's app locales through createConfigurationContext; Robolectric tests pin both paths. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…dumps only our package The result lines above "Vynulovat" wrap as numbers grow and move the button (API 30 emulator: runs silently added up). `dumpsys activity top` timed out on a frozen cached app (API 35), so the View hosts are read from `dumpsys activity <package>`. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…, gate Log on dex bytes Review findings on the Phase 8 diff (/topshit + Stage 2 security review): - build_release.sh fails unless both the APK (apksigner) and the AAB (keytool -printcert -jarfile) carry the upload certificate from ADR-034, refuses a working tree with changes and prints the commit it built. - app/build.gradle.kts refuses a signed build while the configuration cache is active, before any password is read: the cache would store the environment variables' values in plain text under .gradle/. - check_release_apk.py gates on the Log descriptor in the dex bytes (independent of dexdump's format), treats a dump without method code as a tool error (exit 2) and picks the newest installed build-tools, so CI no longer computes it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…upload checklist - accuracy-testing.md: emulator matrix API 28-36 (release build), why Android 9 is not supported, harness notes, battery protocol on the API 34 emulator (scroll, idle, time-in-app sync) with its limits. - README: status through Phase 8, Android 10+, release build and the upload certificate fingerprint. - CLAUDE.md: the emulator AVD and tools/build_release.sh. - play-listing.md: internal testing upload checklist for Honza. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
An app bundle's language splits follow the phone's languages, so a phone in a third language switched to English for this app (Android 13 per-app language) would lack the English strings. Lint AppBundleLocaleChanges flagged it; the bundle's BundleConfig now has the LANGUAGE split dimension negated. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
Summary
Phase 8 of
PLAN.md— the release build, an emulator matrix, a battery protocol and the distribution prep.tools/build_release.shbuilds the APK + AAB from a clean tree only, and fails unless both carry the pinned upload certificate (046f8cd0…669c0e88). It then runs the APK check and prints the commit and SHA-256.android.util.Logcall.tools/check_release_apk.py(in CI) gates on theLandroid/util/Log;descriptor in the dex bytes, flags a debuggable APK and debug-recording literals, and treats an unparseable dexdump as a tool error.Context.inAppLanguage(), with Robolectric tests.AppBundleLocaleChanges).Measured (emulators, release build —
docs/accuracy-testing.md)POST_NOTIFICATIONSprompt.SPEC §54 Definition of Done
TYPE_VIEW_SCROLLEDscrollDeltaX/YcanRetrieveWindowContent=false, typeViewScrolled only (manifest policy + PolicyGuardTest)Battery on real phones (SPEC §39: 1 h / 8 h / 24 h) → new debt V8; ColorOS usage-access revocation + restart → V9.
Gates
GitHub Actions still refuse to start (account billing, see handoff), so this was checked on a clean detached checkout of
f23891dwith the CI commands:testDebugUnitTest lintDebug assembleDebug assembleRelease: 265 JVM tests pass; lint 0 errors, 6 old warnings (SetTextI18nin the debug test list);check_manifest_policy.py(debug + release): ok;check_release_apk.pyon the unsigned release: clean;python3 -m unittest discover -s tools: 44 pass;tools/build_release.shend to end from a clean worktree: signed APK + AAB, certificate pinned, APK clean. The password appears in neither the log nor any of 1 278 build files.Review
/topshit(cumulative diff): pinned the upload certificate for the APK and the AAB; the script accepts only a clean tree and prints the commit; build-tools are resolved in one place.inAppLanguage,device_accuracy.py.🤖 Generated with Claude Code