summaryrefslogtreecommitdiff
path: root/docs/SETTINGS_SPIKE.md
diff options
context:
space:
mode:
authorcirakg <cirakg@cirakg.xyz>2026-10-25 12:46:42 +0100
committercirakg <cirakg@cirakg.xyz>2026-10-25 12:46:42 +0100
commite0384274bbeab999279bdc35bdddbd8a3a451aeb (patch)
tree206abf2390f6bd30d1ddbcc02717f1009b4cc659 /docs/SETTINGS_SPIKE.md
parent6b17954f654d83c754cbdaae37f98689b9a4fcb7 (diff)
docs: record the settings spike and the Forerunner 70 benchmark
Spike (2026-10-21, Android): 8000 characters per field and 64,000 in total arrive; URIs with & save; the mixed special-character string is refused, so the test strings now split it into one group each plus a fake Aegis export. Benchmark: SHA-1 TOTP 18 ms, SHA-512 732 ms, PBKDF2 2,000 iterations per second. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'docs/SETTINGS_SPIKE.md')
-rw-r--r--docs/SETTINGS_SPIKE.md42
1 files changed, 28 insertions, 14 deletions
diff --git a/docs/SETTINGS_SPIKE.md b/docs/SETTINGS_SPIKE.md
index 340670a..a3e2328 100644
--- a/docs/SETTINGS_SPIKE.md
+++ b/docs/SETTINGS_SPIKE.md
@@ -61,23 +61,37 @@ Keep the spike app open on the watch for tests A to H, except where a test says
## Results
-Fill this in (or tell me the values and I'll record them). Date, phone model, Garmin Connect app version (Settings, About) and the watch firmware help explain later differences.
+Run on 2026-10-21 by the project owner with the Store beta of Settings Spike on the Forerunner 70 and an Android phone. The two version numbers were reported as "2.50" and "18.32" without labels; the phone model wasn't recorded.
| Item | Result |
| --- | --- |
-| Date, phone, Garmin Connect version, watch firmware | |
-| A. Longest single field that arrives complete | |
-| A. What happens above that (refused / error / cut to N) | |
-| B. Largest total across the eight fields | |
-| C. Characters that didn't arrive or blocked saving | |
-| D. Status written by the watch visible on the phone (yes/no) | |
-| D. Password field empty after the watch cleared it (yes/no) | |
-| E. Changes arrive while the app is open (yes/no) | |
-| E. Changes arrive while the app is closed, seen at next start (yes/no) | |
-| F. Password field: arrives on the watch, masked on the phone (yes/no each) | |
-| G. Time from Save to the watch updating (short / longest) | |
-| H. Phone-side validation of the number fields (message) | |
-| Other observations | |
+| Date, phone, Garmin Connect version, watch firmware | 2026-10-21, Android phone, versions 2.50 and 18.32 (which is the app and which the firmware is to be confirmed) |
+| A. Longest single field that arrives complete | 8000 characters, the longest string tested |
+| A. What happens above that (refused / error / cut to N) | Not tested: no string longer than 8000 was tried |
+| B. Largest total across the eight fields | 64,000 characters (8 fields of 8000) saved and arrived complete |
+| C. Characters that didn't arrive or blocked saving | The phone **refused to save** the `special` string. An `otpauth://` URI with `&`, `?`, `=`, `:` and `@` saved and arrived. Which of `< > \ " { } %`, the accented letters, `€` or the emoji blocks saving is not known yet: see the follow-up below |
+| D. Status written by the watch visible on the phone (yes/no) | Yes: the phone shows the "seen ... change #N" line and its number goes up |
+| D. Password field empty after the watch cleared it (yes/no) | Yes |
+| E. Changes arrive while the app is open (yes/no) | Yes |
+| E. Changes arrive while the app is closed, seen at next start (yes/no) | Yes |
+| F. Password field: arrives on the watch, masked on the phone (yes/no each) | When the settings were opened again, the field was empty, because the watch clears it after every save (as in D). The "got N chars" line on the watch wasn't reported. The OTP Wallet secret fields, which use the same field type, worked in the real-watch test (YOUR_STEPS 5.2), so the field is usable |
+| G. Time from Save to the watch updating (short / longest) | About 1 second |
+| H. Phone-side validation of the number fields (message) | 301 is rejected by the phone and the settings can't be saved. The switch, list (option C, value 2) and the long number 9999999999 arrive (`switchField: true`, `listField: 2`) |
+| Other observations | None |
+
+### Follow-up for test C
+
+The `special` string mixes many characters, so its failure doesn't say which one the phone rejects. The test-string page now has eight short strings, one per character group (`C1` percent, `C2` angle brackets, `C3` backslash, `C4` double quote, `C5` braces, `C6` accented letters and `€`, `C7` emoji, `C8` a JSON fragment), and `aegis-json`, a complete fake unencrypted Aegis export with one entry. Paste each into Text 2 and save; note which ones the phone refuses. Regenerate the page with `python3 spike/settings/test-strings/make_test_strings.py`.
+
+This decides whether Aegis JSON can be pasted into the import fields at all (it needs `"`, `{`, `}` and sometimes `\`). If the phone refuses those characters, Aegis import goes back to the design table: the fallback is pasting `otpauth://` URIs, which are confirmed to work.
+
+### What the results change
+
+- **Import field size (A, B).** The import design assumed fields of a few hundred characters. One field takes at least 8000 characters and the eight together at least 64,000, so Garmin Connect is not the limit: the watch's 32 KB import buffer is (README 11.2). About 160 compact Aegis entries, or 60 to 80 pretty-printed ones, fit in one sync. The eight `impText` fields and multi-part import stay as they are.
+- **`otpauth://` URIs (C).** They paste as they are, so the parser doesn't need the `;` fallback for `&`.
+- **Write-back (D).** Status lines written by the watch (the forms' **Result** fields) and cleared secret fields show on the phone after reopening the settings.
+- **Processing (E, G).** Changes arrive within about a second while the app is open, and at the next start when it is closed. The app already processes forms on both paths.
+- **Number validation (H).** The phone enforces `min` and `max` itself, so the watch-side range checks are a second line of defence only.
## How the results feed the design