Skip to content

Commit ddd16cc

Browse files
committed
fix: correct stale backup/transfer privacy copy and add CI guard
README.md said device-to-device transfer was "kept" for the personal dictionary, but data_extraction_rules.xml has excluded it from both cloud backup AND D2D transfer since v1.8.85. - README.md: corrected with accurate exclusion language and migration pointer to Settings → Personal dictionary → Export/Import. - docs/PRIVACY_AND_AI.md: corrected §2 and §3 (local-only, gitignored). - scripts/check-backup-privacy-copy.sh: new CI guard greps prose files for stale "transfer kept/allowed" patterns. - .github/workflows/android.yml: wired the guard into pre-build checks.
1 parent 6487a91 commit ddd16cc

3 files changed

Lines changed: 66 additions & 1 deletion

File tree

.github/workflows/android.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ jobs:
6666
- name: Check release-front-door drift
6767
run: bash scripts/check-release-front-door.sh
6868

69+
- name: Check backup/transfer privacy copy
70+
run: bash scripts/check-backup-privacy-copy.sh
71+
6972
- name: Check fork-identity for F-Droid readiness
7073
run: bash scripts/check-fork-identity.sh
7174

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ Published APKs are generated with pinned Gradle, Android Gradle Plugin, Kotlin,
264264
- **Long-press popups:** suppressed on every `KeyVariation.PASSWORD` (Android 17 password-visibility behavior closed on the IME side as of v1.8.44).
265265
- **Personalized learning:** clipboard write / dictionary learn paths skip password and `IME_FLAG_NO_PERSONALIZED_LEARNING` fields.
266266
- **Opt-in addon surfaces (smart-compose, translation, MCP):** every invocation runs through `SensitiveFieldGuard` first; sensitive fields short-circuit to a safe no-result.
267-
- **Personal dictionary backup:** excluded from cloud-backup paths; device-transfer kept.
267+
- **Personal dictionary backup:** excluded from both Android cloud backup and device-to-device transfer. The SQLCipher passphrase is wrapped by an Android Keystore key that is non-exportable, so the ciphertext is undecryptable on a new device. Use Settings → Personal dictionary → Export/Import for explicit local migration.
268268

269269
The public posture is simple: no network permission, no telemetry, no account binding, no cloud learning, and explicit user action before sensitive local data is exported or shared with another app.
270270

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#!/usr/bin/env bash
2+
# scripts/check-backup-privacy-copy.sh
3+
#
4+
# Guard against public prose drifting from the actual data_extraction_rules.xml.
5+
# The rules exclude the personal dictionary, key material, clipboard history,
6+
# learned n-grams, SwiftKey traces, and sync identity from BOTH cloud backup
7+
# and device-to-device transfer. Any prose that says transfer is "kept" or
8+
# "allowed" for these items is misleading.
9+
#
10+
# Exits 0 on pass, 1 on any match.
11+
12+
set -euo pipefail
13+
14+
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
15+
cd "$ROOT_DIR"
16+
17+
errors=0
18+
19+
fail() {
20+
echo "::error::backup-privacy-copy: $*"
21+
errors=$((errors + 1))
22+
}
23+
24+
# Prose files to scan (docs + README).
25+
FILES=(
26+
README.md
27+
docs/PRIVACY_AND_AI.md
28+
docs/THREAT_MODEL.md
29+
docs/SECURITY.md
30+
docs/REPRODUCIBLE_BUILDS.md
31+
)
32+
33+
# Patterns that indicate stale wording about device transfer being preserved.
34+
PATTERNS=(
35+
'device.transfer kept'
36+
'device.transfer.* is allowed'
37+
'device.transfer.* is preserved'
38+
'device.transfer.* is included'
39+
'd2d.* transfer.* allowed'
40+
'd2d.* transfer.* kept'
41+
)
42+
43+
for f in "${FILES[@]}"; do
44+
[ -f "$f" ] || continue
45+
for pat in "${PATTERNS[@]}"; do
46+
matches="$(grep -inP "$pat" "$f" || true)"
47+
if [ -n "$matches" ]; then
48+
while IFS= read -r line; do
49+
fail "${f}: stale backup/transfer wording: ${line}"
50+
done <<< "$matches"
51+
fi
52+
done
53+
done
54+
55+
if [ "$errors" -gt 0 ]; then
56+
echo "backup-privacy-copy: FAIL ($errors stale-wording match(es) found)"
57+
echo "The data_extraction_rules.xml excludes the personal dictionary from"
58+
echo "BOTH cloud backup and device-to-device transfer. Update the prose to match."
59+
exit 1
60+
fi
61+
62+
echo "backup-privacy-copy: OK (no stale transfer wording found)"

0 commit comments

Comments
 (0)