<feed xmlns='http://www.w3.org/2005/Atom'>
<title>otpGarmin, branch main</title>
<subtitle>OTP Wallet for Garmin Connect IQ: offline one-time passwords and barcodes.</subtitle>
<id>https://git.cirakg.xyz/otpGarmin/atom?h=main</id>
<link rel='self' href='https://git.cirakg.xyz/otpGarmin/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/'/>
<updated>2026-10-28T11:05:22+00:00</updated>
<entry>
<title>docs: add public repository and clone URL</title>
<updated>2026-10-28T11:05:22+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-10-28T11:05:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/commit/?id=5dc47b8e8adafb80d96c133f0ead27d0b6bab91a'/>
<id>urn:sha1:5dc47b8e8adafb80d96c133f0ead27d0b6bab91a</id>
<content type='text'>
</content>
</entry>
<entry>
<title>chore: prepare repository for open-source release</title>
<updated>2026-10-28T10:45:11+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-10-28T10:45:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/commit/?id=09ef21af399a60ceb2e45526fe1a7dd94c53819c'/>
<id>urn:sha1:09ef21af399a60ceb2e45526fe1a7dd94c53819c</id>
<content type='text'>
</content>
</entry>
<entry>
<title>build(release): new application ID for the public Store app</title>
<updated>2026-10-27T23:20:57+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-10-27T23:20:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/commit/?id=3096eb7d366683caec24ed5d0a70ac5dae6f624d'/>
<id>urn:sha1:3096eb7d366683caec24ed5d0a70ac5dae6f624d</id>
<content type='text'>
Garmin can't turn a beta app into a public one, so 1.0.0 is published as
a new Store app with a new manifest ID. The watch treats it as a separate
app from the beta: the user guide's Install section explains importing
the entries again and deleting the beta.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>chore(release): 1.0.0, with the Connect IQ Store listing</title>
<updated>2026-10-27T23:03:01+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-10-27T23:03:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/commit/?id=9e5a85fe01e94489198a64a458f9b09584594f80'/>
<id>urn:sha1:9e5a85fe01e94489198a64a458f9b09584594f80</id>
<content type='text'>
The second real-watch round on the Forerunner 70 passed: codes from
otpauth:// links, the 4-digit PIN, touch scrolling and Aegis JSON import.
Version 1.0.0 ships the fixes of the 0.9.0 review.

- docs/STORE_LISTING.md: title, description and What's New for the
  Garmin developer page, with measured character counts.
- docs/store/: hero (1440x720), cover (500x500) and seven round screen
  images, built by tools/store_assets.py from the fr70 goldens.
- CHANGELOG 1.0.0, README status, TESTING round 2 results, YOUR_STEPS
  marked done, fr70 about.png golden at 1.0.0.

make ci green on fr70.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>docs(spike): test C split, only the backslash is refused</title>
<updated>2026-10-27T23:03:01+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-10-26T14:01:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/commit/?id=e5172350151043050098d37b728054eb2e2be9f8'/>
<id>urn:sha1:e5172350151043050098d37b728054eb2e2be9f8</id>
<content type='text'>
Settings spike test C, split (round 2, 2026-10-27, Android): Garmin
Connect refuses to save only C3, the backslash. Every other character
group and an Aegis export without backslashes save, and a real Aegis
export imported on the Forerunner 70, so the import design stays.
Android Aegis writes / as \/ (icons, names with a slash): the user guide
explains replacing \/ with / or removing icons. C3 is a known limitation.

The spike manifest gets a new application id: the old one could not be
uploaded to the Garmin developer page.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(import): splitting pasted otpauth:// links runs no character loop</title>
<updated>2026-10-27T00:08:30+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-10-27T00:08:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/commit/?id=86c11634379ab87238d794f8f9e8bbc991041e4d'/>
<id>urn:sha1:86c11634379ab87238d794f8f9e8bbc991041e4d</id>
<content type='text'>
OtpAuth.splitUris/firstWord looped over every character in one event, so
pasting about 100 links tripped the watchdog (the UI fixture imports Aegis
JSON, so it never ran this path). They now use native searches only. New
make watchdog case uris_100 (13,576 characters, twice per event) trips on
the old code and passes now. fr70: make lint, make test, make watchdog pass.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(pin): the work after a PIN and the change queue run in steps</title>
<updated>2026-10-27T00:01:18+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-10-27T00:01:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/commit/?id=bc4cc19df5f53519ca1aabd3cf161b6d78ffc16c'/>
<id>urn:sha1:bc4cc19df5f53519ca1aabd3cf161b6d78ffc16c</id>
<content type='text'>
After a correct or new PIN, promoting pending entries and applying waiting
"Require PIN" changes ran in the event of the last PBKDF2 step; 16 waiting
changes tripped the watchdog on the Forerunner 70. ChangeQueue.LockJob now
does it in steps while the PIN screen shows "Checking...", saves what it did
to the results and refreshes the glance after Set PIN too.

The list title decrypted every waiting change at each start. Queue items
are now [action, box] (aad OTPW-Q-2 + action code), so they are counted
without decrypting; 0.9.0 items are still read. A replacement is checked
when it arrives and its material is sealed apart (qm.&lt;n&gt;). Large buffers
are wiped and UTF-8-checked in pieces (Jobs.Wiper, Bytes.utf8Prefix,
SealedBox.openKeep/sealKeep). "Phone changes" reads behind "Reading...",
and Confirm all / Reject all act only on the changes shown. Storage full
no longer stops the app at the PIN.

Found by the review of b8addc8/096b5a4 and a new make watchdog test; the
diff was reviewed again and its findings fixed. fr70: make lint, make test
(176), make watchdog (19 cases at two steps per event), make screenshots
pass; list_locked and list_reset goldens show "Results ready (menu)".

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>fix(pin): START never submits on touch; Change PIN asks once after a legacy PIN</title>
<updated>2026-10-26T14:20:20+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-10-26T14:20:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/commit/?id=34daecaa25e5bdd995179a2b4b9d922f8bbb3b54'/>
<id>urn:sha1:34daecaa25e5bdd995179a2b4b9d922f8bbb3b54</id>
<content type='text'>
A legacy PIN (0.8.0 or earlier) on a touch screen was still submitted by
START, and a tap that also arrives as START could submit the digits
typed so far as a counted wrong PIN. The OK key is tapped instead.
"Change PIN" while locked with a legacy PIN asked for the new PIN twice:
the forced new PIN after the unlock is now the change.

Found in the review of b8addc8 and 096b5a4. make test and make
screenshots pass on the Forerunner 70.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>build: test on the Forerunner 70 only by default; ALL=1 for every device</title>
<updated>2026-10-26T13:52:06+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-10-26T13:52:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/commit/?id=5913e3c104c2aa34cc1eb21523419edb437373c4'/>
<id>urn:sha1:5913e3c104c2aa34cc1eb21523419edb437373c4</id>
<content type='text'>
Unit tests, perf, memory, lint builds, screenshots and the watchdog test
run on the owner's Forerunner 70 alone unless ALL=1 is given, which
keeps runs and screenshot reviews short (8 instead of 65 minutes for
the screenshots). make build defaults to the Forerunner 70 too.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>chore(release): 0.9.0, the fixes from the first real-watch round</title>
<updated>2026-10-25T22:51:52+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-10-25T22:51:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/commit/?id=096eebab2add4faba4cd04ab81d325deca17af15'/>
<id>urn:sha1:096eebab2add4faba4cd04ab81d325deca17af15</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
