<feed xmlns='http://www.w3.org/2005/Atom'>
<title>otpGarmin, branch v0.2.0</title>
<subtitle>OTP Wallet for Garmin Connect IQ: offline one-time passwords and barcodes.</subtitle>
<id>https://git.cirakg.xyz/otpGarmin/atom?h=v0.2.0</id>
<link rel='self' href='https://git.cirakg.xyz/otpGarmin/atom?h=v0.2.0'/>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/'/>
<updated>2026-10-18T21:44:18+00:00</updated>
<entry>
<title>docs: record M2 results and bump version to 0.2.0</title>
<updated>2026-10-18T21:44:18+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-10-18T21:44:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/commit/?id=94181d58cf66c5b7b263fd435a344f1cd8872cff'/>
<id>urn:sha1:94181d58cf66c5b7b263fd435a344f1cd8872cff</id>
<content type='text'>
CHANGELOG 0.2.0; PERFORMANCE (simulator benchmarks and what they mean for
the watch); TESTING (vector sources, M2 results, watchdog caveat);
FEASIBILITY (verified: no native HMAC-SHA1, AES-256 works, Long semantics);
README status and targets; developer-guide Monkey C facts.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat(spike): add the M1 settings spike app and make targets</title>
<updated>2026-10-18T21:44:18+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-10-18T21:44:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/commit/?id=ac60fb060414261935ac5e158b26b34e211e1e06'/>
<id>urn:sha1:ac60fb060414261935ac5e158b26b34e211e1e06</id>
<content type='text'>
A separate throwaway app (own app ID, no permissions) that shows what the
Garmin Connect app delivers per settings field and writes values back, to
measure the undocumented settings limits on the real phone and watch.
Includes length-marked test strings, `make spike` / `make spike-sim`,
`make vectors`, and step-by-step instructions in docs/SETTINGS_SPIKE.md.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>test: add cross-checked crypto/OTP vectors, unit tests and stricter screenshots</title>
<updated>2026-10-18T21:44:18+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-10-18T21:44:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/commit/?id=93aa7e3aa291f3328cf34a5a2f86172f41d0affd'/>
<id>urn:sha1:93aa7e3aa291f3328cf34a5a2f86172f41d0affd</id>
<content type='text'>
- gen_vectors.py: RFC/FIPS/NIST vectors recomputed with Python's stdlib
  (openssl for AES) before use, plus seeded cases around SHA padding
  boundaries, 2038 and 2100; generates test/data/Vectors.mc.
- 31 Monkey C tests (hashes, HMAC, PBKDF2, HKDF, AES, sealed records incl.
  every-byte tamper detection, Base32 errors, 100 OTP and 12 Steam
  vectors, clock, jobs) and a benchmark; pass on all four test devices.
- Screenshot tolerance 0.01 %: one changed character no longer passes.
- Golden images updated for version 0.2.0.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat(otp): add Base32 decoding, HOTP, TOTP and Steam Guard codes</title>
<updated>2026-10-18T21:44:18+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-10-18T21:44:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/commit/?id=5646ae7f40dc53c9ebed0b3b6e907cc85fcd5993'/>
<id>urn:sha1:5646ae7f40dc53c9ebed0b3b6e907cc85fcd5993</id>
<content type='text'>
Base32 accepts any case, spaces, hyphens and missing padding, and reports
the exact position of a bad character. TOTP uses 64-bit time, so codes stay
correct after 2038. Steam Guard is a separate, optional code type.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat(crypto): add SHA-512, HMAC, PBKDF2, HKDF, AES-256 records and self-test</title>
<updated>2026-10-18T21:44:18+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-10-18T21:44:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/commit/?id=e47ae684101981a7c20f3270994a61944059c825'/>
<id>urn:sha1:e47ae684101981a7c20f3270994a61944059c825</id>
<content type='text'>
- Sha512: FIPS 180-4 in Monkey C (no native SHA-512), rotations inlined
  with precomputed masks; constants derived from the primes, not typed.
- Hmac: RFC 2104 over SHA-1/256/512 (native HMAC only supports SHA-256).
- Kdf: resumable PBKDF2-HMAC-SHA256 job with calibration bounds
  (2,000-200,000 iterations) and HKDF-SHA256.
- Aes: CBC with PKCS#7 over the native cipher; AES-256 chosen.
- SealedBox: encrypt-then-MAC records (HKDF-split keys, length-prefixed
  aad, constant-time tag check before decryption).
- SelfTest: known-answer tests for every primitive at start-up.
- Bytes (wipe, constant-time equal), Clock (2038-safe widening, trusted
  clock), Jobs (bounded steps against the watchdog, timer runner).

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>docs: add developer, testing and performance guides; record M0 results</title>
<updated>2026-10-18T19:10:37+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-10-18T19:10:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/commit/?id=b70cde45b67e1f6bb65d598d25c1a5184bdab520'/>
<id>urn:sha1:b70cde45b67e1f6bb65d598d25c1a5184bdab520</id>
<content type='text'>
- DEVELOPER_GUIDE: workflow, how the tooling works (verified simulator
  behaviour), conventions and how to add devices.
- TESTING and PERFORMANCE: test layers, M0 results and measured numbers.
- FEASIBILITY: what M0 verified (watchdog 120k/240k, 10 MB storage in
  device profiles, unreliable monkeydo exit code, icon sizes).
- README status, new make targets and layout; CHANGELOG 0.1.0.
- Author/Summary headers on every document, including the original brief.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>feat(app): add minimal watch app with smoke test and per-size icons</title>
<updated>2026-10-18T19:10:37+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-10-18T19:10:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/commit/?id=773df56883b9961b607a1994920f5ef5299423b8'/>
<id>urn:sha1:773df56883b9961b607a1994920f5ef5299423b8</id>
<content type='text'>
The M0 placeholder app: AppBase entry point, home screen with name and
version, debug-only diagnostics (start-up time, memory) and a unit test
that runs in the headless simulator. Builds with strict type checking
and zero warnings for all 72 products; icons.jungle gives every product
a launcher icon of its exact size.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>test(tools): add screenshot, budget and product checks; enforce file headers</title>
<updated>2026-10-18T19:10:37+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-10-18T19:10:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/commit/?id=2292bf700d28ade39cf2d64b45509e6db21034bc'/>
<id>urn:sha1:2292bf700d28ade39cf2d64b45509e6db21034bc</id>
<content type='text'>
- sim_screenshot.py finds the device drawing in the simulator window,
  crops the screen and compares it with approved golden images.
- check_budgets.py reads key=value DIAG/HARNESS lines (the simulator
  console escapes quotes, so JSON was dropped).
- ciq_test_report.py accepts SDK 9.2.0's real summary line
  `PASSED (passed=N, failed=N, errors=N)`; a captured log is a fixture.
- gen_products.py checks all manifest products are watches with
  API 5.0+ and at least 512 KB for apps.
- lint_project.py rule HDR001: every file carries the Author/Summary
  header (JSON keys, PNG text chunks; generated package-lock exempt).
- make_icon.py --all draws one icon per launcher size in use.
- Golden screenshots for fr255s, venusq2, fr70 and fr965.
- 44 tests, warnings as errors, ruff and mypy --strict clean.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>build: complete the Docker pipeline for build, test, screenshots and packaging</title>
<updated>2026-10-18T19:10:37+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-10-18T19:10:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/commit/?id=85f1ecabd7f58f306b2a042376209ac8cf49ab9b'/>
<id>urn:sha1:85f1ecabd7f58f306b2a042376209ac8cf49ab9b</id>
<content type='text'>
- Container scripts now run from the mounted project (no image rebuild
  per script change): build-app.sh (strict -l 3, warnings fail),
  run-unit-tests.sh, screenshots.sh, app-diag.sh (perf/memory),
  lint.sh, package.sh and sim-vnc.sh (noVNC on 127.0.0.1:6080).
- Headless simulator helpers: wait for port 1234, remove the stale
  single-instance lock (~/Sim-dev) that made later starts hang, show
  the simulator log on failure.
- New targets: screenshots-approve, icons; `make lock` re-adds the
  requirements header; pytest treats warnings as errors.
- Author/Summary headers on every build file.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>test(tools): add test-log judge, docs and policy checks with tests</title>
<updated>2026-10-18T18:28:09+00:00</updated>
<author>
<name>cirakg</name>
<email>cirakg@cirakg.xyz</email>
</author>
<published>2026-10-18T18:28:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cirakg.xyz/otpGarmin/commit/?id=2071e2beda763137416ac386d4bb953711ec995d'/>
<id>urn:sha1:2071e2beda763137416ac386d4bb953711ec995d</id>
<content type='text'>
- ciq_test_report.py: decides pass/fail from Run No Evil output instead
  of monkeydo's unreliable exit code; writes JUnit XML.
- check_docs.py: offline check of relative links and GitHub anchors.
- lint_project.py: project rules (headers, no logging outside Diag,
  no secret-like literals, no network APIs or permissions).
- check_budgets.py with budgets.json: perf and memory gates.
- make_icon.py: reproducible launcher icon.
- 31 pytest tests, including Hypothesis fuzzing of the log parser and
  integration checks against the real docs and sources; ruff and mypy
  (strict) clean.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
