v1.2.0 — OFF cache + body-cap streaming + R8 minify
·
266 commits
to develop
since this release
Immutable
release. Only release title and notes can be modified.
[1.2.0] — 2026-05-28
Added
- Offline cache for OFF lookups of non-pantry barcodes. Re-scanning a
product that was previewed (but not added) now resolves locally —
no network call, no 4-host fallback walk. 30-day TTL; cache row is
deleted when the barcode is committed to the pantry. (#48)
Changed
- Release builds now use R8 minify +
shrinkResources. APK size
reduced from 40,523,977 bytes (~40.5 MB) at v1.1.0 to 24,140,473
bytes (~24.1 MB) at v1.2.0 — a 40.4% reduction. (SR-9, refs #36)
Security
- Replace header-only OFF response body cap with streamed enforcement.
The 256 KB cap now fires on chunked responses regardless of
Content-Length advertisement, closing the gap left by the v1.1.0
hotfix. (#52) - R8 strips unused code from the release artifact, reducing attack
surface. Belt-and-braces-keeprules inapp/proguard-rules.pro
preempt the "first-time R8 enable strips reflection target"
symptom for kotlinx.serialization @serializable types
(OffProduct,OffApiEnvelope) and Room entities/DAOs (Product,
OffLookupCacheEntry,ProductDao,OffLookupCacheDao, plus
AppDatabaseandConvertersdefensively). (SR-9, refs #36)
Tests / quality
- 194 → 218 JVM unit tests.
- RNG screenshot harness added (#74 / SR-74) using Robolectric
Native Graphics + golden-PNG diff. Covers icon variants, theme,
font-scale, and Coil image rendering — retires UAT §0 rows 2-4,
§2 rows 1, 2, and 4, §11 last row (greyed-row 45% opacity check),
and v1.2 §11 Coil row. - Scan-flow Compose UI tests (#75 / SR-75) cover OFF-hit, OFF-miss
timeout fallback, in-inventory remove, and not-in-inventory +
switch-to-Add — retires UAT §7 (8 of 9), §8 (5 of 6), §11 (5), §12 (2). - Search UI test (#76 / SR-76) — retires UAT §9 (5 rows).
- Camera permission deep-link + onResume tests (#77 / SR-77) —
retires UAT §4 (5 of 6), §5 (5 of 7), §6 (3 of 8). - Rotation + error-tone tests + detekt rule (#78 / SR-78) — config-change
- error tone; the
ErrorToneRuleextracted to a standalone
:detekt-rulesGradle module with a proof test. Retires UAT §14
(configuration change row) and §15 (error tone).
- error tone; the
- CI emulator job (#79 / SR-79) on
reactivecircus/android-emulator-runner@v2.37.0, API 35, PR-gating
connectedDebugAndroidTestruns. ~5-8 min added per PR. - R8 static-inspection script (#80 / SR-80) verifies
@Serializable+
@Entityclasses survive minification in the release APK. - MIGRATION_1_2 emulator-drive runbook (#81 / SR-81) — script + docs
for on-device migration smoke; retires UAT v1.2 §1 upgrade-install row. - OFF resilience tests (#82 / SR-82) — fallback-chain matrix +
cache offline replay; retires UAT v1.2 §3-5 (3) + §12 (1). - androidTest permission-revoke fix (SR-117 / PR #118) — adds
CameraPermissionGate.isCameraGrantedtest seam so revoking a held
runtime permission no longer kills the shared instrumentation
process. - Room schema baseline committed under
app/schemas/(#57 / SR-17),
unlockingMigrationTestHelper-based migration tests against the
v1 → v2 schema delta. - UAT checklist umbrella closed (#73) — every retired row annotated
with[automated by SR-N]; new "Stays human-only" appendix
enumerates the irreducibly-physical items + the v1.2 OFF CDN chunked
encoding rule. - CLAUDE.md lessons fold (#119) — 6 new entries in "Things that
have bitten past sessions" covering revoke-of-held-permission,
custom AndroidJUnitRunner.newApplication, detekt custom rules in
standalone module, post-tag lockfile untrack, on-device CI catches
what static review can't, GitFlow ruleset constraints.
Install (sideload)
- Download
app-release.apkfrom this release. - Enable "Install unknown apps" for your browser or file manager (Android: Settings → Apps → Special access).
- Open the downloaded APK. The installer will request permission to install; the app updates over v1.0.x / v1.1.x in place (no data loss).
Verify the APK
SHA-256 8be3e781c4837dc433fc6b11b70baa02916e44d9ac4533df4712c2286c8ad366 app-release.apk
size 24,271,545 bytes (~24.27 MB)
Signing certificate (lifetime identity for all v1.x updates):
Subject: CN=Patrick Kuhn, OU=DocGerdSoft, O=DocGerdSoft, L=Schwetzingen, ST=BW, C=DE
SHA-256: ec9a4bb80ccbe56b3aeccf73eb220418be87ac10b1128bdd868b3d0cd87cb3d9
SHA-1: fbd758914b3abeb71321c03b429716dae9e212cc
If you have v1.0.x or v1.1.x installed, the signing cert matches and Android will accept the upgrade-install.
Source
Built reproducibly from tag v1.2.0 at commit b3d4ef02e6bcbb8516c765cd197834244e2500d5.