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
Copy file name to clipboardExpand all lines: RESEARCH_REPORT.md
+22-4Lines changed: 22 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# SwiftFloris Research Report
2
2
3
-
This report summarizes current research conclusions. The full 2026-05-25 research plan is archived at `docs/archive/research/RESEARCH_FEATURE_PLAN_2026-05-25.md`. Deep-research pass refreshed **2026-06-03** (post-v1.8.204), with 2026-06-04 freshness notes through Cycle 13 and v1.8.246 implementation notes.
3
+
This report summarizes current research conclusions. The full 2026-05-25 research plan is archived at `docs/archive/research/RESEARCH_FEATURE_PLAN_2026-05-25.md`. Deep-research pass refreshed **2026-06-03** (post-v1.8.204), with 2026-06-04 freshness notes through Cycle 14 and v1.8.246 implementation notes.
constructor stdout logging is removed, aggregate helper semantics are documented
@@ -38,6 +38,13 @@ must remain local generated output rather than review evidence.
38
38
AndroidX Core `1.19.0` remains blocked on the API 37 behavior-gate because the
39
39
published `core-1.19.0.aar` metadata declares `minCompileSdk=37`.
40
40
41
+
2026-06-04 Cycle 14 note: after the Cycle 13 docs push, `master` is clean at
42
+
`857cfe0` (`v1.8.246-2-g857cfe0`). Cycle 14 rechecked the deferred
43
+
personal n-gram TSV token-safety audit against live bigram/trigram
44
+
normalization, load, and flush paths. This cycle adds R14-1: reject tab,
45
+
newline, carriage-return, NUL, and other ISO control separators before learned
46
+
tokens can enter personal n-gram TSV persistence.
47
+
41
48
2026-06-04 Cycle 13 note: after the Cycle 12 docs push, `master` is clean at
42
49
`3df1e5b` (`v1.8.246-1-g3df1e5b`). Cycle 13 rechecked the deferred
43
50
`totalEntryCount()` / `resetAndAwait()` audit against live personal bigram and
@@ -204,6 +211,7 @@ Top opportunities (one line each):
204
211
25.**Preference-store init splash recovery** — async `initAndroid` failures now stage a crash report, unblock the splash wait, and redirect to crash recovery before normal Settings content renders (R11-1). [Closed]
205
212
26.**Personal n-gram file replacement** — bigram/trigram flush fallback deletes the live file before a successful replacement exists (R12-1, P2). [Verified]
206
213
27.**Personal n-gram stats/reset serialization** — `totalEntryCount()` can enumerate/load persisted bigram/trigram locales outside the reset lock while `resetAndAwait()` clears and deletes those files (R13-1, P2). [Verified]
214
+
28.**Personal n-gram TSV token safety** — learned bigram/trigram tokens can still contain tab/newline/NUL/control separators that corrupt TSV rows or trigram context keys on reload (R14-1, P2). [Verified]
207
215
208
216
No Critical or Major reliability/security defects were found that are not already on the roadmap or in the deferred audit lists. The remaining heavy work (glide model training, Vosk addon, F-Droid submission, device-only visual verification) stays maintainer-gated as the existing roadmap records.
209
217
@@ -287,7 +295,9 @@ Privacy-first multilingual IME. `:app` is Apache-2.0-ceiling, no network permiss
287
295
deletes the destination before a second rename attempt. R12-1 keeps the
288
296
last-known-good n-gram file until replacement succeeds. R13-1 adds the
289
297
adjacent stats/reset consistency gap: `totalEntryCount()` should not reload or
290
-
report stale locales around `resetAndAwait()` cleanup. [Verified]
298
+
report stale locales around `resetAndAwait()` cleanup. R14-1 adds the
299
+
write-time TSV token-safety gap for control separators before persistence.
300
+
[Verified]
291
301
- Established surfaces (autocorrect/SymSpell, glide classifier, clipboard, addons, voice handoff, sync, MCP, hardware-keyboard import) are covered by `COMPLETED.md` and the audits; no net-new gap surfaced beyond what the roadmap already tracks.
292
302
293
303
## Competitive Landscape
@@ -330,6 +340,10 @@ Privacy-first multilingual IME. `:app` is Apache-2.0-ceiling, no network permiss
330
340
bigram/trigram `totalEntryCount()` file enumeration and `ensureLoaded()` under
331
341
the reset-safe boundary, or compute counts from a reset-safe snapshot, so
332
342
Settings stats cannot resurrect or display stale learning counts after reset.
carriage-return, NUL, and other ISO control characters in bigram/trigram
345
+
normalized tokens before they can corrupt tab-separated rows or trigram
346
+
context keys.
333
347
-**[Closed v1.8.219] Remaining diagnostic `printStackTrace()` paths** → R2-2. `RestoreScreen` failure diagnostics now use `flogError`, restore UI copy falls back to the existing "Unknown error" string for null/blank throwable messages, and `CrashUtility.writeToFile` logs through `LogTopic.CRASH_UTILITY`.
334
348
-**[High] Local release ledger drift** → R3-1. Three code-fix commits after
335
349
the v1.8.225 docs marker are untagged and absent from the release ledger.
@@ -423,7 +437,9 @@ Privacy-first multilingual IME. `:app` is Apache-2.0-ceiling, no network permiss
423
437
atomic-replace contract so persistence failures cannot destroy the previous
424
438
locale file. Cycle 13 adds the related read/reset boundary: stats counting
425
439
should share reset serialization or use a reset-safe snapshot before it can
426
-
call `ensureLoaded()` on persisted locale files.
440
+
call `ensureLoaded()` on persisted locale files. Cycle 14 adds the TSV
441
+
precondition boundary: learned tokens must reject control separators before
centralizes leave/mutation/transfer gates. v1.8.232 keeps that policy and
429
445
adds a visible response when Compose back handling blocks the gesture during
@@ -436,7 +452,7 @@ Privacy-first multilingual IME. `:app` is Apache-2.0-ceiling, no network permiss
436
452
437
453
## Security / Privacy / Data Safety
438
454
439
-
No net-new permission or data-egress finding. The settings-search additions are display/navigation only; the no-results Browse all settings action (RA-2), synonym keyword coverage (RA-3), and query-change scroll reset (RA-10) do not weaken the no-network posture. R2-1 and R2-2 closed as local diagnostic-safety work without adding network, telemetry, or broad file export. R11-1 closes the async side of startup diagnostics by surfacing preference-store init failures through the existing local crash recovery path without adding storage, permissions, or outbound data. R12-1 is local personal-prediction durability hardening and does not change dictionary retention, export, permissions, or outbound data. R13-1 is local stats/reset consistency hardening for the same personal n-gram files and likewise does not change retention, export, permissions, or outbound data. R3-2 is also local-only clipboard filtering. R3-3 closed as sync-crypto contract hardening before transport activation, with no new permission or native dependency. R4-1/R4-2/R4-3/R4-4 are closed local correctness/a11y/API-contract work. WS12 and WS10/WS15 are docs/resource-only and do not change permissions, retention, or storage behavior. R5-1 closed as trust-boundary hardening for optional addon APKs: it keeps the no-network addon screen but requires explicit trust before non-co-signed packages become active. R6-1 is local editor critical-section hardening and does not change storage, permissions, or outbound data. R7-1 closed as privacy posture hardening for the existing incognito mode and `FLAG_SECURE` contract, not a permission change. R9-1 is privacy-state hardening for existing local suggestion and smart-compose paths: it keeps the no-network posture and ensures `IME_FLAG_NO_PERSONALIZED_LEARNING` / incognito decisions are request-scoped across async work. R10-1 is local editor-session lifecycle hardening and does not change storage, permissions, or outbound data. R8-1 is UI feedback for an already-blocked dictionary operation path and does not change data retention, dictionary mutation, or export/import permissions. WS13 now explicitly includes the deferred `StickerMediaProvider.openFile` SAF allow-list validation so forged encoded sticker URIs are rejected without broadening file access. The deferred audit lists (`docs/AUDIT_2026-06-02.md`) remain the authority for crypto/parsing/lifecycle hardening; this pass does not duplicate them.
455
+
No net-new permission or data-egress finding. The settings-search additions are display/navigation only; the no-results Browse all settings action (RA-2), synonym keyword coverage (RA-3), and query-change scroll reset (RA-10) do not weaken the no-network posture. R2-1 and R2-2 closed as local diagnostic-safety work without adding network, telemetry, or broad file export. R11-1 closes the async side of startup diagnostics by surfacing preference-store init failures through the existing local crash recovery path without adding storage, permissions, or outbound data. R12-1 is local personal-prediction durability hardening and does not change dictionary retention, export, permissions, or outbound data. R13-1 is local stats/reset consistency hardening for the same personal n-gram files and likewise does not change retention, export, permissions, or outbound data. R14-1 is local write-time token-safety hardening for existing personal n-gram persistence and does not add collection, retention, export, permissions, or outbound data. R3-2 is also local-only clipboard filtering. R3-3 closed as sync-crypto contract hardening before transport activation, with no new permission or native dependency. R4-1/R4-2/R4-3/R4-4 are closed local correctness/a11y/API-contract work. WS12 and WS10/WS15 are docs/resource-only and do not change permissions, retention, or storage behavior. R5-1 closed as trust-boundary hardening for optional addon APKs: it keeps the no-network addon screen but requires explicit trust before non-co-signed packages become active. R6-1 is local editor critical-section hardening and does not change storage, permissions, or outbound data. R7-1 closed as privacy posture hardening for the existing incognito mode and `FLAG_SECURE` contract, not a permission change. R9-1 is privacy-state hardening for existing local suggestion and smart-compose paths: it keeps the no-network posture and ensures `IME_FLAG_NO_PERSONALIZED_LEARNING` / incognito decisions are request-scoped across async work. R10-1 is local editor-session lifecycle hardening and does not change storage, permissions, or outbound data. R8-1 is UI feedback for an already-blocked dictionary operation path and does not change data retention, dictionary mutation, or export/import permissions. WS13 now explicitly includes the deferred `StickerMediaProvider.openFile` SAF allow-list validation so forged encoded sticker URIs are rejected without broadening file access. The deferred audit lists (`docs/AUDIT_2026-06-02.md`) remain the authority for crypto/parsing/lifecycle hardening; this pass does not duplicate them.
440
456
441
457
## UX & Accessibility
442
458
@@ -466,6 +482,8 @@ The keyboard surface already has a strong a11y baseline (`ACCESSIBILITY.md`, `To
466
482
decision is required.
467
483
8. R13-1 needs a focused personal n-gram stats/reset test; no maintainer
468
484
product decision is required.
485
+
9. R14-1 needs focused personal n-gram token-safety tests for control
486
+
separators; no maintainer product decision is required.
0 commit comments