2025-10-10 - 2026-10-10
Overview
2 Releases published by 1 user
Published
v0.2.0
v0.2.0
Published
v0.1.0
v0.1.0
216 Pull requests merged by 1 user
Merged
#504 fix(security): derive key-invalidation and cache-guard decisions from seal state, not the encryptCache setting
Merged
#478 test(migrator): resolve latest exported AccountDatabase schema dynamically
Merged
#471 perf(icloud): respect iCloud Mail IMAP connection & message-size limits
Merged
#470 perf(outlook): respect Microsoft Graph throttling with batching & chunked upload
Merged
#474 ci(e2e): gate the emulator on window focus to fix the RootViewPicker flake (#468)
Merged
#469 perf(gmail): respect Gmail IMAP connection & bandwidth limits in sync/backfill
Merged
#467 test(accountsetup): de-flake URL-open link E2E tests via fake LocalUriHandler
Merged
#463 perf(sync): pace backfill with an inter-slice cooldown and per-run cap
Merged
#464 ci(e2e): restore wedge-capture diagnostics on the matrix E2E legs (#421)
Merged
#460 ci(path-filter): skip E2E for scripts/docs/.claude-only PRs (#420)
Merged
#459 perf(sync): pause background backfill while a message is opening
Merged
#458 chore(test): migrate v1 createComposeRule/createAndroidComposeRule usages to v2
Merged
#434 fix(notifications): verify notification-tap origin before opening a message (#307)
Merged
#436 feat(sync): graceful degradation + exponential backoff on provider throttling
Merged
#435 fix(mail): below-cut mail/richtext perf & correctness nits (#298)
Merged
#454 ci(e2e): converge matrix emulator boot on e2e-preview manual boot
Merged
#450 ci(gradle): pin Gradle distribution against published SHA-256
Merged
#437 fix(ui): address below-cut UI/Compose review nits (#308)
Merged
#446 ci(e2e): harden matrix emulator + system-image install against corrupt-zip (extend #389)
Merged
#438 refactor(data): tighten data-core atomicity, chunking, and dead code (#313)
Merged
#439 feat(onboarding): Battery -> Unrestricted help animation (#174)
Merged
#433 ci(mergify): Phase 2 - enable batching (batch_size 5) (#410)
Merged
#428 fix(mail): gracefully fall back when the IMAP server lacks UIDPLUS
Merged
#429 perf(data): route MailBackfiller.persistBatch through batched updateHeaderContents
Merged
#430 feat(auth): detect "IMAP disabled" AUTHENTICATE failures and prompt the user to enable IMAP
Merged
#427 fix(push): persist credentials before IdleService watches a new account (#403)
Merged
#426 feat(onboarding): pre-auth Outlook IMAP-enablement screen (help/settings links + Sign In)
Merged
#425 fix(cache): close SQLCipher nativeOpen crash-loop gaps beyond resolveOpenMode (#359)
Merged
#422 ci(mergify): fix auto-queue - migrate to merge_protections_settings/auto_merge_conditions (deprecation 2026-07-16)
Merged
#424 feat(security): encrypt persisted reports at rest when cache encryption is on (#369)
Merged
#406 ci: capture thread-dump + service state on an E2E wedge to prove the root cause (#404)
Merged
#414 ci(mergify): upgrade configuration to current format
Merged
#419 refactor(scripts): fold cold-fetch pause-hook A/B into device-testing harness (#405)
Merged
#418 test(compose): re-ratchet JaCoCo line-coverage floor to 0.84 (#386)
Merged
#395 feat(debug): dev-only pause/halt mail-fetch hook for test harnesses (#393)
Merged
#417 test(compose): Robolectric JVM tests — app shell & lock gate host (#384)
Merged
#416 test(compose): Robolectric JVM tests — mailbox screen + folder drawer (#383)
Merged
#415 test(compose): Robolectric JVM tests — compose editor screen (#382)
Merged
#401 test(compose): Robolectric JVM tests for settings screens (#380)
Merged
#400 test(compose): Robolectric JVM tests for the reader screen (#381)
Merged
#397 test(compose): Robolectric JVM tests — mail list screens drafts/outbox/reports (batch 4/9)
Merged
#412 ci(mergify): implement Phase 1 — serial merge queue (require-up-to-date KEPT ON)
Merged
#408 docs(ci): propose Mergify merge-queue integration spec (#407)
Merged
#402 ci: skip the E2E matrix for test-only/docs PRs via a paths-filter + skip-tolerant gate (#399)
Merged
#396 test(compose): Robolectric JVM tests for onboarding & lock screens (#377)
Merged
#398 test(compose): Robolectric JVM tests for account setup screens (#378)
Merged
#394 test(compose): Robolectric JVM tests for rich-text format controls (#376)
Merged
#367 fix(security): fail closed on cache-encryption load failure + StrongBox-back keys (#359)
Merged
#391 ci: retry + cache Android SDK/emulator setup to survive corrupt-zip sdkmanager failures (#389)
Merged
#375 test(compose): Robolectric JVM Compose testing infra + PoC (#373)
Merged
#388 ci(e2e): capture logcat + emulator/system diagnostics across the E2E matrix (#387)
Merged
#374 test(settings): cancel viewModelScope before db.close in SignaturesScreenTest to fix a Room teardown race
Merged
#372 ci: shard the API 37 preview E2E into 2 parallel shards + retry parity
Merged
#370 feat(scripts): device-testing perf harness
Merged
#371 chore(preflight): run jacocoTestCoverageVerification in the fast gate
Merged
#368 perf(mail): enable IMAP connection reuse by default with a hardened cache
Merged
#366 fix(push): stop IdleService dataSync FGS crash-loop on exhausted 24h cap (#354)
Merged
#365 feat(reporting): PII-free latency breadcrumbs on the message-open path (#358)
Merged
#353 ci: extract traffic-control into its own workflow file
Merged
#285 perf(db): covering index for unified-inbox summary scans
Merged
#352 ci: trigger CI with the PAT so dispatches don't need manual approval (#351)
Merged
#317 fix(auth): drop redundant second Outlook token request on sign-in
Merged
#350 ci: traffic-controller owns CI triggering (GITHUB_TOKEN updates, priority-ordered dispatch)
Merged
#339 chore(docs): require app logging in the definition of done
Merged
#344 docs: plain-English README for the CI traffic-controller
Merged
#348 feat(logging): detekt guard banning android.util.Log outside AppLog (#331)
Merged
#340 feat(logging): auth/lock -> AppLog + breadcrumbs (#326)
Merged
#347 ci: run traffic-controller unit tests as a gate job
Merged
#345 ci: extract traffic-controller into a testable Python module (#342)
Merged
#338 feat(logging): connectivity/send → AppLog + breadcrumbs, scrub email PII (#328)
Merged
#336 feat(logging): stragglers -> AppLog (#330)
Merged
#341 feat(logging): sync-engine breadcrumbs via AppLog (#329)
Merged
#337 feat(logging): DB/keystore -> AppLog + breadcrumbs (#327)
Merged
#335 ci(e2e): boot diagnostics + verbose/debug logging on the API 37 preview job
Merged
#333 feat(logging): AppLog seam — record scrubbed throwables + accountLogRef (#325)
Merged
#332 test-infra: port local_instrumented.sh to Python + rewire preflight off GMD (#281)
Merged
#323 feat(ci): no-regression JVM coverage gate scoped to the testable surface
Merged
#316 fix(reporting): scrub PII from crash stack traces + move ReportStore scan off the main thread
Merged
#321 fix(ui): reader Reply quotes original + guard one-shot actions against double-tap
Merged
#320 perf/fix(data): batch sync updates, paging tiebreaker, migration-registration test
Merged
#315 fix(data): account-lifecycle data integrity (non-destructive upsert, id normalization, deleteAccount cleanup)
Merged
#318 fix(mail): targeted + batch expunge (stop deleting unrelated \Deleted mail)
Merged
#314 fix(push): handle Service.onTimeout to survive the dataSync FGS runtime cap
Merged
#293 test(coverage): high-value branch-coverage additions
Merged
#291 test(coverage): close clean JVM-testable coverage gaps
Merged
#287 test-infra: make local_instrumented.sh CWD-independent
Merged
#286 chore(ui): migrate LocalClipboardManager to LocalClipboard
Merged
#283 test(reporting): ReportUpload testability seams + push IdleService E2E
Merged
#282 test(db): instrumented cold-open of a pre-encrypted cache
Merged
#280 test-infra: reliable local instrumented-test helper (connectedDebugAndroidTest + emulator hygiene)
Merged
#279 test(coverage): lane 5 follow-up — UI tests for remaining screens
Merged
#278 test(db): pin native-lib-before-keyed-open at the DatabaseModule factory site
Merged
#273 fix(mailbox): keep the inbox pager warm on reader return so it doesn't flash empty
Merged
#277 test(onboarding): assert the Outlook onboarding button launches the browser
Merged
#274 test(coverage): lane 5 — Compose screens E2E coverage
Merged
#240 feat(settings): reorder accounts by drag in settings
Merged
#272 test(sync): instrumented cache-lock deferral for PruneWorker/BackfillWorker
Merged
#245 feat(reporting): add PII-free account summary to debug reports
Merged
#270 test(coverage): lane 3 — persistence, DAOs & migrations to >=95%
Merged
#234 feat(search): Unicode-aware case-insensitive search via casefold columns
Merged
#242 feat(reporting): purge crash/problem reports older than a month while charging
Merged
#266 ci(preflight): add API 35 and API 37 emulator E2E to preflight
Merged
#268 ci(runners): P0 & broken-target preemption; P1-P9 yield without bumping in-progress
Merged
#267 build(gmd): cap managed-device emulators to 1 concurrent (serial) to avoid local VT-x contention
Merged
#265 ci(runners): priority-based runner orchestration via P0–P9 labels
Merged
#253 fix(sync): bound the foreground fetch window by the age cutoff in age retention
Merged
#264 ci(autoupdate): drop synchronize trigger, keep draft PRs updated
Merged
#263 fix(reporting): auto-prompt to submit a crash only on first re-open, for a legitimate <24h crash
Merged
#261 test(coverage): lane 2 — sync, workers, transport & auth to >=95%
Merged
#260 ci(autoupdate): also trigger on pull_request so newly-opened PRs update immediately
Merged
#256 test(coverage): lane 4 — ViewModels & non-UI modules to >=95%
Merged
#254 test(coverage): lane 1 — repository, mappers & domain logic to >=95%
Merged
#252 docs(claude): require unit + latest-API E2E in the definition of done
Merged
#241 build: wire up JaCoCo code-coverage reporting
Merged
#244 ci(autoupdate): keep all open PRs up to date (drop the auto_merge filter)
Merged
#238 chore(ui): migrate hiltViewModel to its new androidx.hilt.lifecycle.viewmodel.compose package
Merged
#231 test(sync): cover the cache-lock gate on SyncWorker/SendWorker + the provisioner await
Merged
#230 build(release): build the release APK for ARM only (arm64-v8a + armeabi-v7a)
Merged
#229 fix(sync): gate PruneWorker & BackfillWorker on the encrypted-cache lock
Merged
#223 perf(mailbox): page the per-account folder view and search
Merged
#222 ci(e2e): retry the API-29 emulator boot to absorb the android-emulator-runner keyevent race
Merged
#216 perf(mailbox): bound paging window (maxSize) and memoize per-row timestamp
Merged
#209 chore(preflight): compile androidTest source set in the fast gate
Merged
#208 fix(cache): load SQLCipher native lib before every keyed open
Merged
#207 chore(security): validate Content-ID before MIME/Graph use
Merged
#206 chore(security): whitelist font-family on HTML emit
Merged
#203 fix(compose): release persistable URI permissions for attachments/inline images
Merged
#201 feat(compose): inline images
Merged
#199 feat(compose): debounced periodic draft autosave
Merged
#200 feat(compose): font family picker with bundled open-source fonts
Merged
#198 feat(compose): paragraph alignment
Merged
#197 feat(compose): remember last-used font and size
Merged
#194 feat(accountsetup): warn against using account password for app password
Merged
#195 feat(compose): font size control
Merged
#196 feat(onboarding): require GPL-3.0 license agreement as the first screen
Merged
#190 feat(accountsetup): add AOL provider with app-password help and IMAP/SMTP presets
Merged
#189 feat(compose): add font color and text highlight to the formatting toolbar
Merged
#191 test(sync): interleaving tests for the ungated sync↔backfill and sync↔prune pairs
Merged
#188 perf(reader): render message body once, move openMessage IO off-main, drop wasted work
Merged
#185 feat(accountsetup): add Yahoo app-password/2FA help in onboarding
Merged
#184 feat(compose): add strikethrough to the formatting toolbar
Merged
#170 fix(reader): propagate SEEN flag off the message-open critical path
Merged
#178 feat(settings): reorder the Advanced settings section
Merged
#173 feat(onboarding): deep-link battery step nearer the per-app background-activity screen (best-effort)
Merged
#175 feat(settings): let the user set a default mail account
Merged
#181 fix(notifications): reliably open the tapped message from a new-mail notification
Merged
#183 feat(reporting): require a reply-to email and a 200-char minimum on problem reports
Merged
#180 feat(accountsetup): add iCloud app-password/2FA help in onboarding
Merged
#182 ci: run autoupdate in the CI_CD environment so it can read AUTOUPDATE_TOKEN
Merged
#171 feat(reporting): show a clear confirmation dialog after submitting a problem report
Merged
#168 fix(onboarding): request notification permission after welcome screen renders
Merged
#176 test(compose): add RichTextEditor unit + ComposeScreen UI coverage
Merged
#179 docs(compose): correct RichTextEditor toolbar accessibility KDoc
Merged
#166 fix(accountsetup): show 2-Step Verification link before app-password link for Gmail
Merged
#167 fix(mailbox): show spinner during initial folder fetch instead of empty state
Merged
#169 feat(settings): reorder top-level settings sections and add appearance subtext
Merged
#165 fix(mailbox): anchor account-switcher dropdown to its trigger
Merged
#131 spike(imap): prototype flag-gated connection reuse for folder-open
Merged
#146 ci: auto-update armed PRs; drop dead merge_group trigger
Merged
#145 refactor(security): de-duplicate AES-GCM Keystore plumbing and unify the authenticator policy
Merged
#144 test(security): cover the app-lock security core (seal exchange, unlock classification, policy table)
Merged
#140 fix(reader): render inline cid: images in HTML emails
Merged
#137 fix(di): defer database provisioning off the Hilt inject path
Merged
#138 fix(security): harden app-lock recovery restart (self-restart race + lost syncNow enqueue)
Merged
#135 refactor(security): derive backup exclusion set from DatabaseFiles
Merged
#132 feat(contacts): move contacts permission to onboarding + settings
Merged
#139 ci: trigger on merge_group for GitHub merge queue
Merged
#136 feat(reader): collapse extra attachments into an accordion
Merged
#130 perf(mailbox): page the unified "All inboxes" list (#124)
Merged
#118 fix(security): keep accounts/credentials out of the auth-bound cache DB (#111)
Merged
#126 test(imap): investigate folder-open round-trip latency (#125)
Merged
#122 feat(folders): persist the server-reported IMAP hierarchy delimiter
Merged
#123 perf(mailbox): scope the message-list query to the viewed folder in SQL
Merged
#121 refactor(security): app-lock UI plumbing cleanup (snackbar, LifecycleEventEffect, LocalActivity, dead availability())
Merged
#120 refactor(folders): consolidate, externalize, and memoize folder-label resolution
Merged
#119 fix(security): app-lock lifecycle consistency (grace across Back, passphrase eviction limits)
Merged
#117 refactor(folders): derive roleOf and isServerSpecial from one attribute table
Merged
#115 feat(onboarding): link Google 2FA help from Gmail app-password step
Merged
#114 fix(sync): re-enqueue periodic work with UPDATE so upgrades re-apply the schedule
Merged
#112 fix(sync): make backfill age floor robust to out-of-order dates and guard lowestSyncedUid
Merged
#116 feat(drawer): unread-count badges per folder and bold accounts with unread mail
Merged
#113 test(folders): cover attributes-to-specialUse wiring; fix FolderLabelsTest fidelity claim
Merged
#45 [needs careful review] feat(security): screen-lock app gate + auth-bound cache decrypt (#22)
Merged
#108 fix(folders): apply label disambiguation to picker and app bar; fix self-referential and transient labels
Merged
#109 feat(sync): gate full-content fetch on Wi-Fi/battery; IDLE polls at low battery
Merged
#106 fix(mailbox): derive plain-text preview snippets from HTML bodies
Merged
#107 test(db): add Room migration tests with MigrationTestHelper
Merged
#105 ci(release): add tag-triggered signed-release and store-publish workflow
Merged
#46 [needs careful review] feat(sync): default fetch-all history + device-only retention (#12, #13)
Merged
#97 docs(play): add privacy policy, data-safety mapping, and permissions justification
Merged
#110 feat(message): move message actions from dropdown to top-bar icons
Merged
#92 fix(mail): prefer special-use folder when resolving move-by-role destination
Merged
#91 chore(fdroid): add F-Droid metadata, license audit, and anti-feature docs
Merged
#80 feat(compose): prompt before sending when a mentioned attachment is missing
Merged
#82 feat(compose): collapse Cc/Bcc into expandable links under the To field
Merged
#81 feat(richtext): parameterized styles, alignment/image/base-style channels, HTML round-trip
Merged
#57 fix(notifications): open the tapped message from a new-mail notification
Merged
#55 chore(preflight): add ktlintCheck + detekt to the fast gate
Merged
#54 fix(mailbox): de-duplicate folder names in the drawer
Merged
#52 fix(mailbox): project message list to avoid CursorWindow overflow
Merged
#50 feat(onboarding): opt-in to unrestricted battery/background usage
Merged
#48 docs: refresh README for onboarding/app-password/rich-compose/opt-in features
Merged
#47 feat(compose): rich HTML editor, multipart send, and signatures
Merged
#43 feat(mailto): handle mailto: links and email share intents
Merged
#42 feat(reporting): opt-in debug reporting client (capture + review/submit)
Merged
#44 feat(onboarding): first-run flow, vendor picker, and app-password setup
Merged
#41 feat(backup): opt-in Android Backup for settings only
Merged
#40 refactor(auth): remove dead Gmail OAuth code path
Merged
#8 chore: Kotlin linting (ktlint + detekt), CLAUDE.md tooling, and CI enforcement
Merged
#7 feat: per-account settings for signatures and notifications
Merged
#6 Fix dark-mode reader readability + make API 37 E2E required
Merged
#5 feat: long-press multi-select, aggressive prefetch, and download indicators
Merged
#4 ci: fix hung API 37 preview emulator job
Merged
#3 Add IMAP folder navigation drawer + per-API E2E CI matrix
Merged
#2 Fix Outlook sign-in crash and complete the OAuth login flow
Merged
#1 Fix/code review findings
2 Pull requests proposed by 1 user
Proposed
#423 WIP: spike(security): characterize #359 SQLCipher SDK-37/16KB-page failure on-device
Proposed
#472 WIP: perf(yahoo): respect Yahoo/AOL IMAP limits & avoid the 1-hour auth lockout
225 Issues closed from 1 user
Closed
#479 fix(security): key-invalidation policy keys off encryptCache setting, not seal state — can permanently brick the encrypted cache
Closed
#477 test(migrator): validate migrator DDL against the latest exported AccountDatabase schema, not a hardcoded version
Closed
#363 perf(icloud): respect iCloud Mail IMAP connection & message-size limits
Closed
#364 perf(outlook): respect Microsoft Graph throttling with batching & chunked upload
Closed
#468 ci(e2e): fix intermittent emulator app-window-focus loss flaking Espresso RootViewPicker tests
Closed
#361 perf(gmail): respect Gmail IMAP connection & bandwidth limits in sync/backfill
Closed
#356 perf(sync): stop backfill running flat-out — inter-slice cooldown/backoff so it doesn't saturate the account
Closed
#373 test(compose): enable Compose UI unit testing via Robolectric (shrink JaCoCo exclusions, then re-ratchet the floor)
Closed
#421 ci(e2e): restore matrix-leg wedge-capture without hanging reactivecircus (watchdog or manual-boot)
Closed
#420 ci(path-filter): scripts/-only changes still trigger the full E2E matrix (e.g. #419)
Closed
#355 perf(sync): pause background backfill while a message is opening (prioritize interactive IMAP fetches)
Closed
#385 chore(test): migrate v1 createComposeRule/createAndroidComposeRule usages to v2
Closed
#432 Manual-boot convergence
Closed
#307 review(domain/platform): below-cut nits
Closed
#360 feat(sync): graceful degradation + exponential backoff on provider throttling (429 / Too Many Requests / auth lockout)
Closed
#298 review(mail/richtext): below-cut perf & correctness nits
Closed
#448 ci(e2e): harden matrix emulator boot vs API-33 boot race (converge on e2e-preview manual-boot)
Closed
#308 review(ui): below-cut nits
Closed
#443 ci(e2e): harden android-emulator-runner emulator/system-image install against corrupt-zip (extend #389)
Closed
#313 review(data-core): below-cut nits
Closed
#174 Onboarding: help animation showing how to enable unrestricted battery usage
Closed
#410 ci(mergify): Phase 2 — batching (BLOCKED on require-up-to-date decision)
Closed
#319 mail: graceful fallback when the IMAP server lacks UIDPLUS (targeted expunge throws)
Closed
#322 perf(data): route MailBackfiller.persistBatch through batched updateHeaderContents
Closed
#390 feat(auth): detect "IMAP disabled" AUTHENTICATE failures and prompt the user to enable IMAP
Closed
#403 fix(push): IdleService starts before credentials persist — transient "No stored credentials" at account-add
Closed
#411 feat(onboarding): pre-auth Outlook IMAP-enablement screen (help/settings links + Sign In)
Closed
#413 ci(mergify): Phase 1 active but not embarking PRs — investigate on dashboard before switchover
Closed
#359 bug: SQLCipher UnsatisfiedLinkError — encrypted cache nativeOpen fails (likely 16 KB page size) on SDK 37
Closed
#369 feat(security): encrypt persisted problem/crash reports at rest when cache encryption is on
Closed
#357 perf(reader): make first message-open fast independent of backfill (prefetch visible bodies + warm IMAP connection)
Closed
#404 ci: capture definitive diagnostics on an E2E emulator wedge (prove the root cause before fixing)
Closed
#386 test(compose): re-ratchet the JaCoCo line-coverage floor once Compose tests stable (FINAL)
Closed
#409 ci(mergify): implement Phase 1 — serial merge queue (require-up-to-date KEPT ON)
Closed
#389 ci: harden Android SDK/emulator setup against "Error reading Zip content" sdkmanager failures (retry + cache)
Closed
#405 refactor(scripts): fold the proven cold-fetch pause-hook A/B flow into the device-testing harness
Closed
#393 feat(debug): dev-only pause/halt mail-fetch hook for test harnesses
Closed
#358 perf(observability): add PII-free AppLog latency breadcrumbs to the reader / openMessage path
Closed
#383 test(compose): Robolectric JVM tests — mailbox screen + folder drawer, Paging (batch 8/9)
Closed
#381 test(compose): Robolectric JVM tests — reader screen, WebView caveat (batch 6/9)
Closed
#378 test(compose): Robolectric JVM tests — account setup screens (batch 3/9)
Closed
#384 test(compose): Robolectric JVM tests — app shell & lock gate host (batch 9/9)
Closed
#382 test(compose): Robolectric JVM tests — compose editor screen (batch 7/9)
Closed
#380 test(compose): Robolectric JVM tests — settings screens (batch 5/9)
Closed
#379 test(compose): Robolectric JVM tests — mail list screens drafts/outbox/reports (batch 4/9)
Closed
#407 ci: investigate Mergify merge queue (free for OSS) and propose an integration spec
Closed
#399 ci: path-filter the E2E matrix so test-only/docs PRs skip it (cut CI load, unblock the cascade)
Closed
#377 test(compose): Robolectric JVM tests — onboarding & lock screens (batch 2/9)
Closed
#392 fix(scripts): device-testing harness portability + robustness (file-based dump, UTF-8 I/O, breadcrumb readiness, row-selection)
Closed
#376 test(compose): Robolectric JVM tests — rich-text format controls (batch 1/9)
Closed
#387 ci(e2e): extend the #334 API-37 boot/E2E diagnostics to all emulator E2E jobs (API 29-36 matrix)
Closed
#354 fix(push): IdleService dataSync FGS crash-loop — START_STICKY restart into exhausted 24h cap throws ForegroundServiceStartNotAllowedException
Closed
#187 perf(db): covering index for unified-inbox summary scans (deferred / needs migration)
Closed
#351 ci(fix #350): trigger CI with the PAT (GITHUB_TOKEN dispatch needs manual approval)
Closed
#306 fix(auth): drop the redundant 2nd Outlook token request on sign-in (extra onboarding failure point)
Closed
#349 ci: traffic-controller owns CI triggering (GITHUB_TOKEN updates, PAT triggers by priority) — end the cascade
Closed
#343 docs: plain-English README for the CI traffic-controller (as it stands)
Closed
#324 epic: strangler-migrate debug logging to AppLog (useful, PII-safe report breadcrumbs)
Closed
#331 chore(detekt): forbid android.util.Log outside AppLog — strangler guard (#324)
Closed
#326 refactor(auth): route AppLockViewModel/AccountSetupViewModel logging through AppLog (#324)
Closed
#346 ci: run the traffic-controller Python unit tests as a CI gate job
Closed
#342 ci: extract the traffic-controller into a testable Python module (rewrite off inline bash)
Closed
#328 refactor(connectivity): route ImapClient/SendWorker/IdleService through AppLog + scrub email PII (#324)
Closed
#297 review(mail/reporting): below-cut security & robustness follow-ups
Closed
#330 refactor(restart): route RestartActivity logging through AppLog (#324)
Closed
#329 feat(sync): add PII-safe AppLog breadcrumbs to the sync engine (#324)
Closed
#327 refactor(data): route DB/keystore logging through AppLog (#324)
Closed
#334 ci(e2e): capture boot diagnostics + verbose/debug logging on the API 37 preview job
Closed
#325 feat(reporting): AppLog seam — record throwables, StackTraceScrubber, accountLogRef (#324)
Closed
#281 test-infra: port local dev scripts to Python (cross-platform) + rewire preflight off GMD
Closed
#251 test(coverage): lane 6 — coverage ratchet gate (enforce >=95% in CI)
Closed
#290 build(jacoco): scope coverage to the JVM-testable surface (exclude Compose UI / framework / debug)
Closed
#296 perf(reporting): move ReportStore initial scan off the main thread
Closed
#294 security(reporting): scrub PII (host:port, emails) from crash-report stack traces
Closed
#303 fix(reader): Reply from an open email drops the quoted original (bare compose) — use buildReplyDraft
Closed
#304 fix(ui): guard one-shot action buttons against double-tap (duplicate signatures/reports/uploads)
Closed
#312 test(data): assert DatabaseModule registered migrations == the declared set
Closed
#310 perf(data): batch MessageDao header/body updates in one transaction on the sync path
Closed
#311 fix(data): append id tiebreaker to paged message ORDER BY (pagination correctness)
Closed
#299 fix(data): deleteAccount leaves the account's attachment cache files + draft URI grants on disk
Closed
#305 fix(accounts): normalize (lowercase) email when deriving the account id to prevent duplicate accounts
Closed
#309 fix(data): AccountDao.upsert(REPLACE) cascade-deletes signatures+settings on account re-add
Closed
#295 fix(mail): targeted + batch expunge in ImapClient (avoid deleting unrelated \Deleted mail)
Closed
#302 fix(push): handle Service.onTimeout for the 24/7 dataSync FGS (push silently dies after ~6h on Android 14+)
Closed
#289 test(coverage): high-value branch-coverage additions (RichText, VMs, MailRepositoryImpl)
Closed
#288 test(coverage): close the clean JVM-testable coverage gaps (~11 files → ~95% logic)
Closed
#284 test-infra: local_instrumented.sh builds the wrong tree when CWD != repo root
Closed
#237 chore(ui): migrate LocalClipboardManager to LocalClipboard (suspend clipboard API)
Closed
#257 test(reporting): add testability seams for ReportUpload* + E2E cover push IdleService
Closed
#221 test(db): instrumented cold-open of a pre-encrypted cache (process-isolated SQLCipher regression)
Closed
#269 test-infra: local GMD emulator tests fail (snapshot timeout) — use connectedDebugAndroidTest for local runs
Closed
#275 test(coverage): lane 5 follow-up — UI tests for the remaining OAuth/permission + static screens
Closed
#233 ci(perf): performance regression check — fail PRs that regress key benchmarks from baseline
Closed
#220 test(db): pin "native lib loaded before keyed open" at the DatabaseModule factory site
Closed
#258 ci: investigate unit-test sharding in CI (implement if worthwhile)
Closed
#219 perf(mailbox): reader→inbox return flashes "no messages" and reloads (empty-state gate + cold LazyPagingItems)
Closed
#276 test(onboarding): E2E — tapping the Outlook onboarding button launches the browser for OAuth
Closed
#250 test(coverage): lane 5 — Compose screens E2E coverage
Closed
#164 Allow user to re-order accounts in the settings view
Closed
#226 test(sync): instrumented cache-lock deferral for PruneWorker/BackfillWorker
Closed
#271 ci(autoupdate): don't rebase a PR while its CI is mid-run — cancel-in-progress discards the running build
Closed
#235 feat(debug-report): capture account count + per-account provider/auth-type, and attach recent app logs
Closed
#248 test(coverage): lane 3 — persistence, DAOs & migrations to >=95%
Closed
#232 perf(search): Unicode-aware case-insensitive search via a casefold column (approach A)
Closed
#239 feat(reporting): purge crash/problem reports older than 1 month, on charger connect
Closed
#193 sync: age-based retention re-downloads pruned messages on low-traffic mailboxes (window not bounded by age cutoff)
Closed
#262 ci(autoupdate): drop synchronize trigger (stop runner storm), keep draft PRs updated
Closed
#255 fix(reporting): auto-prompt to submit a crash only on first re-open, for a legitimate <24h crash
Closed
#247 test(coverage): lane 2 — sync, workers, transport & auth to >=95%
Closed
#259 ci(autoupdate): also trigger on pull_request so newly-opened PRs update immediately
Closed
#249 test(coverage): lane 4 — ViewModels & non-UI modules to >=95%
Closed
#246 test(coverage): lane 1 — repository, mappers & domain logic to >=95%
Closed
#192 build: wire up JaCoCo code-coverage reporting
Closed
#243 ci(autoupdate): keep ALL open PRs up to date, not just auto-merge-armed ones
Closed
#236 chore(ui): migrate hiltViewModel to its new androidx.hilt.lifecycle.viewmodel.compose package
Closed
#225 test(sync): unit-cover the cache-lock gate on every pre-auth DB entry point
Closed
#227 perf(search): restore Unicode-aware case-insensitive search (examine most performant approach)
Closed
#224 fix(sync): gate PruneWorker & BackfillWorker on EncryptedCacheGuard (defer when the cache is locked)
Closed
#214 perf(mailbox): page the per-account folder view and search (currently whole folder/inbox in memory)
Closed
#218 ci(e2e): converge the matrix e2e job on the e2e-preview manual-boot pattern (definitive boot-race fix)
Closed
#217 ci(e2e): retry the API-29 emulator boot to absorb the android-emulator-runner keyevent race
Closed
#213 perf(mailbox): remember() per-row relative-time formatting to cut per-recomposition allocation
Closed
#212 perf(mailbox): bound the unified-inbox paging window with PagingConfig.maxSize
Closed
#211 chore(preflight): compile androidTest source set in the fast gate
Closed
#210 fix(cache): encrypted cache crash-loops on launch (UnsatisfiedLinkError, SQLiteConnection.nativeOpen)
Closed
#204 chore(security): validate Content-ID before use in MIME header / Graph payload
Closed
#205 chore(security): whitelist font-family against FontRegistry on HTML emit
Closed
#77 feat(compose): inline images
Closed
#177 Compose: debounced periodic draft autosave (not just on exit)
Closed
#72 feat(compose): font family picker with bundled open-source fonts
Closed
#76 feat(compose): paragraph alignment
Closed
#78 feat(compose): remember last-used font and size
Closed
#160 All pre-filled IMAP options should include the disclaimer "Do not try to use your account password. It will not work. You must use an app password."
Closed
#73 feat(compose): font size control
Closed
#172 Onboarding: require GPL-3.0 license agreement as the first screen
Closed
#154 Add pre-filled AOL IMAP settings
Closed
#156 Add AOL app specific password instructions
Closed
#74 feat(compose): font color
Closed
#75 feat(compose): text highlight
Closed
#53 Harden the two ungated sync↔maintenance concurrency pairs (follow-up from #46)
Closed
#186 perf(reader): faster cached message-open — single WebView render, off-main IO, no wasted openMessage work
Closed
#37 Rich compose: multipart/alternative send + reply/forward quoting
Closed
#38 Rich compose: signatures
Closed
#155 Add Yahoo specific app password instructions
Closed
#71 feat(compose): strikethrough formatting
Closed
#148 Opening messages is still very slow, even with all messages downloaded
Closed
#162 Advanced Settings hierarchy
Closed
#150 Onboarding flow should deep link directly to the Background activity page for the app, the screen with the "Optimized" and "Unrestricted" options
Closed
#163 Allow user to set a default mail account
Closed
#157 Bug - regression from prior changes - notification now does not load directly to the email message it displays again
Closed
#159 Report a Problem requires a description of at least 200 characters and improvements to submission process
Closed
#153 Include the same kind of help instructions for iCloud mail during onboarding as Google for 2FA and app passwords
Closed
#161 Report a problem confirmation experience
Closed
#151 Notification prompt timing
Closed
#36 Rich compose: HTML editor + formatting toolbar
Closed
#152 Google 2FA article button should precede the app password button visually for logical flow
Closed
#149 When a folder is open and it is making a network request with no prior messages to display, it should show a wait spinner rather than showing "No messages to display" until the network request completes
Closed
#158 Settings hierarchy list
Closed
#147 Account list dropdown in drawer anchors to the bottom left roughly instead of directly below where it is located near the top
Closed
#125 Investigate IMAP folder-open latency (follow-up to #86)
Closed
#102 refactor(security): de-duplicate AES-GCM Keystore plumbing and unify the authenticator policy
Closed
#100 test(security): cover the app-lock security core (seal exchange, unlock classification, policy table)
Closed
#133 Inline images in HTML emails render as attachments instead of embedded in the body
Closed
#93 provideDatabase blocks on DataStore + Keystore at Hilt inject time (potential ANR)
Closed
#99 fix(security): harden app-lock recovery restart (self-restart race + lost syncNow enqueue)
Closed
#103 refactor(security): single source of truth for the cache DB filename/sidecars
Closed
#128 Contacts permission: show a rationale explaining recipient autocomplete before requesting
Closed
#129 Contacts autocomplete: allow enabling it later after the user declines
Closed
#127 Onboarding: move the contacts-access request out of compose into a dedicated onboarding step
Closed
#134 Reader: collapse multiple attachments into an expandable accordion ("See x more attachments")
Closed
#124 Mailbox: page the unified "All inboxes" view (follow-up to #86)
Closed
#111 fix(security): keep accounts/credentials out of the auth-bound cache DB so key invalidation doesn't sign the user out
Closed
#66 Folder model: persist the IMAP hierarchy delimiter instead of re-inferring it in parentOf()
Closed
#86 Improve message loading performance
Closed
#104 refactor(security): app-lock UI plumbing cleanup (snackbar, LifecycleEventEffect, LocalActivity, dead availability())
Closed
#69 providerLabel: consolidate provider-brand host matching
Closed
#68 i18n: move folder-label disambiguation patterns into strings.xml
Closed
#67 FolderDrawer: memoize label resolution, resolver early-return, fail-fast lookups
Closed
#101 fix(security): app-lock lifecycle consistency (grace across Back, evict passphrase on re-lock)
Closed
#62 Folder labels: add \Important (RFC 8457) so [Gmail]/Important counts as special-use
Closed
#65 Folder model: derive roleOf and isServerSpecial from one attribute-to-role table
Closed
#98 Gmail IMAP in onboarding should link to Google's help article on setting up 2FA
Closed
#96 Periodic WorkManager jobs use KEEP, so interval/constraint changes don't apply on upgrade
Closed
#94 Backfill age floor can stop early on out-of-order Date/UID, leaving a history gap
Closed
#95 uid <= 0 row poisons MessageDao.lowestSyncedUid, causing backfill to under-fetch a folder
Closed
#84 Bolded text for accounts with unread emails
Closed
#83 Unread message count label per folder
Closed
#64 Testing: cover the attributes-to-specialUse wiring; fix FolderLabelsTest fixture fidelity claim
Closed
#22 Screen unlock and decrypt
Closed
#61 Folder labels: transient wrong provider suffix while switching accounts in the open drawer
Closed
#59 Folder labels: move-to picker and app-bar title still show ambiguous duplicate names
Closed
#60 Folder labels: 'Sent [Sent]' self-referential label when two top-level folders share a role
Closed
#90 IMAP IDLE (push email) shuts down and temporarily reverts to pulling every 15 minutes at or below 20% battery
Closed
#88 Default fetch all content policy should be on Wi-Fi only
Closed
#89 Fetch all content should temporarily stop regardless of setting when phone reaches 20% battery or less
Closed
#85 Render or otherwise correctly display HTML content in preview snippets
Closed
#63 Testing: add Room migration tests (MigrationTestHelper), starting with 11 to 12
Closed
#19 Modify release workflow for automated publication to app stores
Closed
#17 Google Play compliance work
Closed
#87 Message options should be icons on the top bar rather than a dropdown
Closed
#58 Move-by-role (Spam/Archive/Trash) can silently file mail into the wrong same-role folder
Closed
#16 F-Droid compliance work
Closed
#9 Onboarding flow
Closed
#79 Compose: remind about missing attachment when the message mentions one
Closed
#70 feat(richtext): parameterized styles, alignment/image/base-style channels, HTML round-trip
Closed
#30 Onboarding: "add another account?" prompt + first-account landing
Closed
#31 Onboarding: E2E test + docs/strings
Closed
#28 Onboarding: preconfigured provider registry (Gmail/Yahoo/iCloud)
Closed
#29 Onboarding: app-password guided setup screen
Closed
#26 Onboarding: first-run navigation scaffold + welcome
Closed
#27 Onboarding: account vendor picker
Closed
#56 fix(notifications): tapping a new-mail notification does not open that email
Closed
#51 fix: CursorWindow overflow crash in MessageDao.observeAll() (SELECT * pulls full body into 2MB window)
Closed
#49 Onboarding: opt-in to unrestricted battery/background usage
Closed
#10 Debugging Submission client
Closed
#23 Compose aesthetics: rounded corners
Closed
#14 Rich email composition and signatures
Closed
#13 Configurable message retention
Closed
#12 Default fetch all mail
Closed
#20 README update
Closed
#25 Enable default mail app
Closed
#33 Debug reporting: report review & opt-in submit
Closed
#32 Debug reporting: error/crash capture + "Report a problem" entry point
Closed
#21 Google Backup inclusion
Closed
#39 Remove dead Gmail OAuth code path
265 Issues created by 1 user
Opened
#9 Onboarding flow
Opened
#10 Debugging Submission client
Opened
#11 Debugging ingest pipeline
Opened
#12 Default fetch all mail
Opened
#13 Configurable message retention
Opened
#14 Rich email composition and signatures
Opened
#15 Detailed code review/audit
Opened
#16 F-Droid compliance work
Opened
#17 Google Play compliance work
Opened
#18 Samsung Galaxy Store: manual publication steps
Opened
#19 Modify release workflow for automated publication to app stores
Opened
#20 README update
Opened
#21 Google Backup inclusion
Opened
#22 Screen unlock and decrypt
Opened
#23 Compose aesthetics: rounded corners
Opened
#24 QA/bug fix pass
Opened
#25 Enable default mail app
Opened
#26 Onboarding: first-run navigation scaffold + welcome
Opened
#27 Onboarding: account vendor picker
Opened
#28 Onboarding: preconfigured provider registry (Gmail/Yahoo/iCloud)
Opened
#29 Onboarding: app-password guided setup screen
Opened
#30 Onboarding: "add another account?" prompt + first-account landing
Opened
#31 Onboarding: E2E test + docs/strings
Opened
#32 Debug reporting: error/crash capture + "Report a problem" entry point
Opened
#33 Debug reporting: report review & opt-in submit
Opened
#34 Debug ingest: Worker ingest + PII anonymization + encrypted R2 storage
Opened
#35 Debug ingest: weekly cron publishes remaining reports as GitHub issues
Opened
#36 Rich compose: HTML editor + formatting toolbar
Opened
#37 Rich compose: multipart/alternative send + reply/forward quoting
Opened
#38 Rich compose: signatures
Opened
#39 Remove dead Gmail OAuth code path
Opened
#49 Onboarding: opt-in to unrestricted battery/background usage
Opened
#51 fix: CursorWindow overflow crash in MessageDao.observeAll() (SELECT * pulls full body into 2MB window)
Opened
#53 Harden the two ungated sync↔maintenance concurrency pairs (follow-up from #46)
Opened
#56 fix(notifications): tapping a new-mail notification does not open that email
Opened
#58 Move-by-role (Spam/Archive/Trash) can silently file mail into the wrong same-role folder
Opened
#59 Folder labels: move-to picker and app-bar title still show ambiguous duplicate names
Opened
#60 Folder labels: 'Sent [Sent]' self-referential label when two top-level folders share a role
Opened
#61 Folder labels: transient wrong provider suffix while switching accounts in the open drawer
Opened
#62 Folder labels: add \Important (RFC 8457) so [Gmail]/Important counts as special-use
Opened
#63 Testing: add Room migration tests (MigrationTestHelper), starting with 11 to 12
Opened
#64 Testing: cover the attributes-to-specialUse wiring; fix FolderLabelsTest fixture fidelity claim
Opened
#65 Folder model: derive roleOf and isServerSpecial from one attribute-to-role table
Opened
#66 Folder model: persist the IMAP hierarchy delimiter instead of re-inferring it in parentOf()
Opened
#67 FolderDrawer: memoize label resolution, resolver early-return, fail-fast lookups
Opened
#68 i18n: move folder-label disambiguation patterns into strings.xml
Opened
#69 providerLabel: consolidate provider-brand host matching
Opened
#70 feat(richtext): parameterized styles, alignment/image/base-style channels, HTML round-trip
Opened
#71 feat(compose): strikethrough formatting
Opened
#72 feat(compose): font family picker with bundled open-source fonts
Opened
#73 feat(compose): font size control
Opened
#74 feat(compose): font color
Opened
#75 feat(compose): text highlight
Opened
#76 feat(compose): paragraph alignment
Opened
#77 feat(compose): inline images
Opened
#78 feat(compose): remember last-used font and size
Opened
#79 Compose: remind about missing attachment when the message mentions one
Opened
#83 Unread message count label per folder
Opened
#84 Bolded text for accounts with unread emails
Opened
#85 Render or otherwise correctly display HTML content in preview snippets
Opened
#86 Improve message loading performance
Opened
#87 Message options should be icons on the top bar rather than a dropdown
Opened
#88 Default fetch all content policy should be on Wi-Fi only
Opened
#89 Fetch all content should temporarily stop regardless of setting when phone reaches 20% battery or less
Opened
#90 IMAP IDLE (push email) shuts down and temporarily reverts to pulling every 15 minutes at or below 20% battery
Opened
#93 provideDatabase blocks on DataStore + Keystore at Hilt inject time (potential ANR)
Opened
#94 Backfill age floor can stop early on out-of-order Date/UID, leaving a history gap
Opened
#95 uid <= 0 row poisons MessageDao.lowestSyncedUid, causing backfill to under-fetch a folder
Opened
#96 Periodic WorkManager jobs use KEEP, so interval/constraint changes don't apply on upgrade
Opened
#98 Gmail IMAP in onboarding should link to Google's help article on setting up 2FA
Opened
#99 fix(security): harden app-lock recovery restart (self-restart race + lost syncNow enqueue)
Opened
#100 test(security): cover the app-lock security core (seal exchange, unlock classification, policy table)
Opened
#101 fix(security): app-lock lifecycle consistency (grace across Back, evict passphrase on re-lock)
Opened
#102 refactor(security): de-duplicate AES-GCM Keystore plumbing and unify the authenticator policy
Opened
#103 refactor(security): single source of truth for the cache DB filename/sidecars
Opened
#104 refactor(security): app-lock UI plumbing cleanup (snackbar, LifecycleEventEffect, LocalActivity, dead availability())
Opened
#111 fix(security): keep accounts/credentials out of the auth-bound cache DB so key invalidation doesn't sign the user out
Opened
#124 Mailbox: page the unified "All inboxes" view (follow-up to #86)
Opened
#125 Investigate IMAP folder-open latency (follow-up to #86)
Opened
#127 Onboarding: move the contacts-access request out of compose into a dedicated onboarding step
Opened
#128 Contacts permission: show a rationale explaining recipient autocomplete before requesting
Opened
#129 Contacts autocomplete: allow enabling it later after the user declines
Opened
#133 Inline images in HTML emails render as attachments instead of embedded in the body
Opened
#134 Reader: collapse multiple attachments into an expandable accordion ("See x more attachments")
Opened
#141 Release: create app signing keystore and add publishing secrets to CI
Opened
#142 Google Play: manual Play Console publication steps
Opened
#143 F-Droid: submit to fdroiddata and fix release-tag versionCode hygiene
Opened
#147 Account list dropdown in drawer anchors to the bottom left roughly instead of directly below where it is located near the top
Opened
#148 Opening messages is still very slow, even with all messages downloaded
Opened
#149 When a folder is open and it is making a network request with no prior messages to display, it should show a wait spinner rather than showing "No messages to display" until the network request completes
Opened
#150 Onboarding flow should deep link directly to the Background activity page for the app, the screen with the "Optimized" and "Unrestricted" options
Opened
#151 Notification prompt timing
Opened
#152 Google 2FA article button should precede the app password button visually for logical flow
Opened
#153 Include the same kind of help instructions for iCloud mail during onboarding as Google for 2FA and app passwords
Opened
#154 Add pre-filled AOL IMAP settings
Opened
#155 Add Yahoo specific app password instructions
Opened
#156 Add AOL app specific password instructions
Opened
#157 Bug - regression from prior changes - notification now does not load directly to the email message it displays again
Opened
#158 Settings hierarchy list
Opened
#159 Report a Problem requires a description of at least 200 characters and improvements to submission process
Opened
#160 All pre-filled IMAP options should include the disclaimer "Do not try to use your account password. It will not work. You must use an app password."
Opened
#161 Report a problem confirmation experience
Opened
#162 Advanced Settings hierarchy
Opened
#163 Allow user to set a default mail account
Opened
#164 Allow user to re-order accounts in the settings view
Opened
#172 Onboarding: require GPL-3.0 license agreement as the first screen
Opened
#174 Onboarding: help animation showing how to enable unrestricted battery usage
Opened
#177 Compose: debounced periodic draft autosave (not just on exit)
Opened
#186 perf(reader): faster cached message-open — single WebView render, off-main IO, no wasted openMessage work
Opened
#187 perf(db): covering index for unified-inbox summary scans (deferred / needs migration)
Opened
#192 build: wire up JaCoCo code-coverage reporting
Opened
#193 sync: age-based retention re-downloads pruned messages on low-traffic mailboxes (window not bounded by age cutoff)
Opened
#204 chore(security): validate Content-ID before use in MIME header / Graph payload
Opened
#205 chore(security): whitelist font-family against FontRegistry on HTML emit
Opened
#210 fix(cache): encrypted cache crash-loops on launch (UnsatisfiedLinkError, SQLiteConnection.nativeOpen)
Opened
#211 chore(preflight): compile androidTest source set in the fast gate
Opened
#212 perf(mailbox): bound the unified-inbox paging window with PagingConfig.maxSize
Opened
#213 perf(mailbox): remember() per-row relative-time formatting to cut per-recomposition allocation
Opened
#214 perf(mailbox): page the per-account folder view and search (currently whole folder/inbox in memory)
Opened
#215 perf(mailbox): async image loading (Coil) when avatars/images are introduced
Opened
#217 ci(e2e): retry the API-29 emulator boot to absorb the android-emulator-runner keyevent race
Opened
#218 ci(e2e): converge the matrix e2e job on the e2e-preview manual-boot pattern (definitive boot-race fix)
Opened
#219 perf(mailbox): reader→inbox return flashes "no messages" and reloads (empty-state gate + cold LazyPagingItems)
Opened
#220 test(db): pin "native lib loaded before keyed open" at the DatabaseModule factory site
Opened
#221 test(db): instrumented cold-open of a pre-encrypted cache (process-isolated SQLCipher regression)
Opened
#224 fix(sync): gate PruneWorker & BackfillWorker on EncryptedCacheGuard (defer when the cache is locked)
Opened
#225 test(sync): unit-cover the cache-lock gate on every pre-auth DB entry point
Opened
#226 test(sync): instrumented cache-lock deferral for PruneWorker/BackfillWorker
Opened
#227 perf(search): restore Unicode-aware case-insensitive search (examine most performant approach)
Opened
#232 perf(search): Unicode-aware case-insensitive search via a casefold column (approach A)
Opened
#233 ci(perf): performance regression check — fail PRs that regress key benchmarks from baseline
Opened
#235 feat(debug-report): capture account count + per-account provider/auth-type, and attach recent app logs
Opened
#236 chore(ui): migrate hiltViewModel to its new androidx.hilt.lifecycle.viewmodel.compose package
Opened
#237 chore(ui): migrate LocalClipboardManager to LocalClipboard (suspend clipboard API)
Opened
#239 feat(reporting): purge crash/problem reports older than 1 month, on charger connect
Opened
#243 ci(autoupdate): keep ALL open PRs up to date, not just auto-merge-armed ones
Opened
#246 test(coverage): lane 1 — repository, mappers & domain logic to >=95%
Opened
#247 test(coverage): lane 2 — sync, workers, transport & auth to >=95%
Opened
#248 test(coverage): lane 3 — persistence, DAOs & migrations to >=95%
Opened
#249 test(coverage): lane 4 — ViewModels & non-UI modules to >=95%
Opened
#250 test(coverage): lane 5 — Compose screens E2E coverage
Opened
#251 test(coverage): lane 6 — coverage ratchet gate (enforce >=95% in CI)
Opened
#255 fix(reporting): auto-prompt to submit a crash only on first re-open, for a legitimate <24h crash
Opened
#257 test(reporting): add testability seams for ReportUpload* + E2E cover push IdleService
Opened
#258 ci: investigate unit-test sharding in CI (implement if worthwhile)
Opened
#259 ci(autoupdate): also trigger on pull_request so newly-opened PRs update immediately
Opened
#262 ci(autoupdate): drop synchronize trigger (stop runner storm), keep draft PRs updated
Opened
#269 test-infra: local GMD emulator tests fail (snapshot timeout) — use connectedDebugAndroidTest for local runs
Opened
#271 ci(autoupdate): don't rebase a PR while its CI is mid-run — cancel-in-progress discards the running build
Opened
#275 test(coverage): lane 5 follow-up — UI tests for the remaining OAuth/permission + static screens
Opened
#276 test(onboarding): E2E — tapping the Outlook onboarding button launches the browser for OAuth
Opened
#281 test-infra: port local dev scripts to Python (cross-platform) + rewire preflight off GMD
Opened
#284 test-infra: local_instrumented.sh builds the wrong tree when CWD != repo root
Opened
#288 test(coverage): close the clean JVM-testable coverage gaps (~11 files → ~95% logic)
Opened
#289 test(coverage): high-value branch-coverage additions (RichText, VMs, MailRepositoryImpl)
Opened
#290 build(jacoco): scope coverage to the JVM-testable surface (exclude Compose UI / framework / debug)
Opened
#294 security(reporting): scrub PII (host:port, emails) from crash-report stack traces
Opened
#295 fix(mail): targeted + batch expunge in ImapClient (avoid deleting unrelated \Deleted mail)
Opened
#296 perf(reporting): move ReportStore initial scan off the main thread
Opened
#297 review(mail/reporting): below-cut security & robustness follow-ups
Opened
#298 review(mail/richtext): below-cut perf & correctness nits
Opened
#299 fix(data): deleteAccount leaves the account's attachment cache files + draft URI grants on disk
Opened
#300 security(threat-model): 'encrypt cache' doesn't cover account-metadata DB or attachment payloads
Opened
#301 review(security/sync): below-cut lifecycle & robustness nits
Opened
#302 fix(push): handle Service.onTimeout for the 24/7 dataSync FGS (push silently dies after ~6h on Android 14+)
Opened
#303 fix(reader): Reply from an open email drops the quoted original (bare compose) — use buildReplyDraft
Opened
#304 fix(ui): guard one-shot action buttons against double-tap (duplicate signatures/reports/uploads)
Opened
#305 fix(accounts): normalize (lowercase) email when deriving the account id to prevent duplicate accounts
Opened
#306 fix(auth): drop the redundant 2nd Outlook token request on sign-in (extra onboarding failure point)
Opened
#307 review(domain/platform): below-cut nits
Opened
#308 review(ui): below-cut nits
Opened
#309 fix(data): AccountDao.upsert(REPLACE) cascade-deletes signatures+settings on account re-add
Opened
#310 perf(data): batch MessageDao header/body updates in one transaction on the sync path
Opened
#311 fix(data): append id tiebreaker to paged message ORDER BY (pagination correctness)
Opened
#312 test(data): assert DatabaseModule registered migrations == the declared set
Opened
#313 review(data-core): below-cut nits
Opened
#319 mail: graceful fallback when the IMAP server lacks UIDPLUS (targeted expunge throws)
Opened
#322 perf(data): route MailBackfiller.persistBatch through batched updateHeaderContents
Opened
#324 epic: strangler-migrate debug logging to AppLog (useful, PII-safe report breadcrumbs)
Opened
#325 feat(reporting): AppLog seam — record throwables, StackTraceScrubber, accountLogRef (#324)
Opened
#326 refactor(auth): route AppLockViewModel/AccountSetupViewModel logging through AppLog (#324)
Opened
#327 refactor(data): route DB/keystore logging through AppLog (#324)
Opened
#328 refactor(connectivity): route ImapClient/SendWorker/IdleService through AppLog + scrub email PII (#324)
Opened
#329 feat(sync): add PII-safe AppLog breadcrumbs to the sync engine (#324)
Opened
#330 refactor(restart): route RestartActivity logging through AppLog (#324)
Opened
#331 chore(detekt): forbid android.util.Log outside AppLog — strangler guard (#324)
Opened
#334 ci(e2e): capture boot diagnostics + verbose/debug logging on the API 37 preview job
Opened
#342 ci: extract the traffic-controller into a testable Python module (rewrite off inline bash)
Opened
#343 docs: plain-English README for the CI traffic-controller (as it stands)
Opened
#346 ci: run the traffic-controller Python unit tests as a CI gate job
Opened
#349 ci: traffic-controller owns CI triggering (GITHUB_TOKEN updates, PAT triggers by priority) — end the cascade
Opened
#351 ci(fix #350): trigger CI with the PAT (GITHUB_TOKEN dispatch needs manual approval)
Opened
#354 fix(push): IdleService dataSync FGS crash-loop — START_STICKY restart into exhausted 24h cap throws ForegroundServiceStartNotAllowedException
Opened
#355 perf(sync): pause background backfill while a message is opening (prioritize interactive IMAP fetches)
Opened
#356 perf(sync): stop backfill running flat-out — inter-slice cooldown/backoff so it doesn't saturate the account
Opened
#357 perf(reader): make first message-open fast independent of backfill (prefetch visible bodies + warm IMAP connection)
Opened
#358 perf(observability): add PII-free AppLog latency breadcrumbs to the reader / openMessage path
Opened
#359 bug: SQLCipher UnsatisfiedLinkError — encrypted cache nativeOpen fails (likely 16 KB page size) on SDK 37
Opened
#360 feat(sync): graceful degradation + exponential backoff on provider throttling (429 / Too Many Requests / auth lockout)
Opened
#361 perf(gmail): respect Gmail IMAP connection & bandwidth limits in sync/backfill
Opened
#362 perf(yahoo): respect Yahoo/AOL IMAP limits & avoid the 1-hour auth lockout
Opened
#363 perf(icloud): respect iCloud Mail IMAP connection & message-size limits
Opened
#364 perf(outlook): respect Microsoft Graph throttling with batching & chunked upload
Opened
#369 feat(security): encrypt persisted problem/crash reports at rest when cache encryption is on
Opened
#373 test(compose): enable Compose UI unit testing via Robolectric (shrink JaCoCo exclusions, then re-ratchet the floor)
Opened
#376 test(compose): Robolectric JVM tests — rich-text format controls (batch 1/9)
Opened
#377 test(compose): Robolectric JVM tests — onboarding & lock screens (batch 2/9)
Opened
#378 test(compose): Robolectric JVM tests — account setup screens (batch 3/9)
Opened
#379 test(compose): Robolectric JVM tests — mail list screens drafts/outbox/reports (batch 4/9)
Opened
#380 test(compose): Robolectric JVM tests — settings screens (batch 5/9)
Opened
#381 test(compose): Robolectric JVM tests — reader screen, WebView caveat (batch 6/9)
Opened
#382 test(compose): Robolectric JVM tests — compose editor screen (batch 7/9)
Opened
#383 test(compose): Robolectric JVM tests — mailbox screen + folder drawer, Paging (batch 8/9)
Opened
#384 test(compose): Robolectric JVM tests — app shell & lock gate host (batch 9/9)
Opened
#385 chore(test): migrate v1 createComposeRule/createAndroidComposeRule usages to v2
Opened
#386 test(compose): re-ratchet the JaCoCo line-coverage floor once Compose tests stable (FINAL)
Opened
#387 ci(e2e): extend the #334 API-37 boot/E2E diagnostics to all emulator E2E jobs (API 29-36 matrix)
Opened
#389 ci: harden Android SDK/emulator setup against "Error reading Zip content" sdkmanager failures (retry + cache)
Opened
#390 feat(auth): detect "IMAP disabled" AUTHENTICATE failures and prompt the user to enable IMAP
Opened
#392 fix(scripts): device-testing harness portability + robustness (file-based dump, UTF-8 I/O, breadcrumb readiness, row-selection)
Opened
#393 feat(debug): dev-only pause/halt mail-fetch hook for test harnesses
Opened
#399 ci: path-filter the E2E matrix so test-only/docs PRs skip it (cut CI load, unblock the cascade)
Opened
#403 fix(push): IdleService starts before credentials persist — transient "No stored credentials" at account-add
Opened
#404 ci: capture definitive diagnostics on an E2E emulator wedge (prove the root cause before fixing)
Opened
#405 refactor(scripts): fold the proven cold-fetch pause-hook A/B flow into the device-testing harness
Opened
#407 ci: investigate Mergify merge queue (free for OSS) and propose an integration spec
Opened
#409 ci(mergify): implement Phase 1 — serial merge queue (require-up-to-date KEPT ON)
Opened
#410 ci(mergify): Phase 2 — batching (BLOCKED on require-up-to-date decision)
Opened
#411 feat(onboarding): pre-auth Outlook IMAP-enablement screen (help/settings links + Sign In)
Opened
#413 ci(mergify): Phase 1 active but not embarking PRs — investigate on dashboard before switchover
Opened
#420 ci(path-filter): scripts/-only changes still trigger the full E2E matrix (e.g. #419)
Opened
#421 ci(e2e): restore matrix-leg wedge-capture without hanging reactivecircus (watchdog or manual-boot)
Opened
#431 E2E Background watchdog
Opened
#432 Manual-boot convergence
Opened
#443 ci(e2e): harden android-emulator-runner emulator/system-image install against corrupt-zip (extend #389)
Opened
#448 ci(e2e): harden matrix emulator boot vs API-33 boot race (converge on e2e-preview manual-boot)
Opened
#451 ci: pin/verify all remaining CI downloads against published checksums
Opened
#457 perf(sync): Spike out if a small number of multiple connections (2-3) improves performance, particularly for requesting user-tapped cold opens
Opened
#468 ci(e2e): fix intermittent emulator app-window-focus loss flaking Espresso RootViewPicker tests
Opened
#477 test(migrator): validate migrator DDL against the latest exported AccountDatabase schema, not a hardcoded version
Opened
#479 fix(security): key-invalidation policy keys off encryptCache setting, not seal state — can permanently brick the encrypted cache
Opened
#480 fix(compose): rich-text formatting, links and inline images destroyed by the next keystroke
Opened
#481 fix(reader): delete from reader bypasses trash policy and permanently expunges without confirmation
Opened
#482 fix(send): attachment staging swallows failures and runs blocking I/O on the main thread
Opened
#483 fix(accounts): deleteAccount leaves outbox rows, staged attachments and URI grants — re-added account resurrects and sends stale mail
Opened
#484 fix(security): MIME filename sanitizing to '.' or '..' escapes the attachment dir and crashes message open
Opened
#485 fix(mail): openMessage does OAuth token refresh before serving a fully-cached body
Opened
#486 fix(persistence): drafts and outbox live in the wipeable cache DB — user-authored mail lost on key-invalidation wipe
Opened
#487 fix(sync): a burst of more than 50 new messages between syncs leaves a permanent message gap
Opened
#488 fix(sync): UIDVALIDITY never stored or checked — stale UIDs corrupt the cache and misdirect destructive ops
Opened
#489 fix(send): drainOutbox re-sends rows parked as 'may have sent' — duplicate emails
Opened
#490 fix(graph): response-body IOException escapes raw instead of GraphTransportException(mayHaveSent=true)
Opened
#491 fix(compose): swapHtmlSignature with null bodyHtml drops the typed body
Opened
#492 fix(compose): closing the screen mid-send cancels the send and silently loses the message
Opened
#493 fix(compose): replies ignore Reply-To and prefill the wrong address
Opened
#494 fix(mailbox): folder identity is case-sensitive but INBOX isn't — servers reporting 'Inbox' split the mailbox in two
Opened
#495 fix(sync): background prefetch loop never consults AccountThrottleGate
Opened
#496 fix(sync): SMTP send failures never feed AccountThrottleGate
Opened
#497 review(compose/send): unverified triage findings from 2026-07-09 whole-repo review (12 medium, 13 low)
Opened
#498 review(mailbox/reader): unverified triage findings from 2026-07-09 whole-repo review (11 medium, 13 low)
Opened
#499 review(mail/push): unverified triage findings from 2026-07-09 whole-repo review (12 medium, 13 low)
Opened
#500 review(persistence): unverified triage findings from 2026-07-09 whole-repo review (10 medium, 15 low)
Opened
#501 review(security): unverified triage findings from 2026-07-09 whole-repo review (5 medium, 12 low)
Opened
#502 review(settings/onboarding): unverified triage findings from 2026-07-09 whole-repo review (1 medium, 12 low)
Opened
#503 review(sync): unverified triage findings from 2026-07-09 whole-repo review (14 medium, 11 low)