aboutsummaryrefslogtreecommitdiff
path: root/docs/DEVELOPER_GUIDE.md
diff options
context:
space:
mode:
authorcirakg <cirakg@cirakg.xyz>2026-10-27 01:01:18 +0100
committercirakg <cirakg@cirakg.xyz>2026-10-27 01:01:18 +0100
commitbc4cc19df5f53519ca1aabd3cf161b6d78ffc16c (patch)
tree3242a63f603882d723bd0d718d043c30a9f11784 /docs/DEVELOPER_GUIDE.md
parent34daecaa25e5bdd995179a2b4b9d922f8bbb3b54 (diff)
fix(pin): the work after a PIN and the change queue run in steps
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.<n>). 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 <noreply@anthropic.com>
Diffstat (limited to 'docs/DEVELOPER_GUIDE.md')
-rw-r--r--docs/DEVELOPER_GUIDE.md4
1 files changed, 3 insertions, 1 deletions
diff --git a/docs/DEVELOPER_GUIDE.md b/docs/DEVELOPER_GUIDE.md
index 74eff63..d9b7c98 100644
--- a/docs/DEVELOPER_GUIDE.md
+++ b/docs/DEVELOPER_GUIDE.md
@@ -87,7 +87,9 @@ The simulator is a GTK program. The scripts start it on a virtual display (Xvfb
- Anything long runs as a `Jobs.Job` with a bounded step (`Kdf.ITERATIONS_PER_STEP` = 100).
- Screens compute at most one SHA-512 code per event, in a timer event separate from drawing.
- The scripted UI flow runs on the 255S profile, so a regression trips there.
- - **M8 found that step sizes guessed from "bytecodes per loop" were 2 to 3 times too large**: a simple loop iteration costs 50 to 70 counted bytecodes, not 10 to 20. Every step of the 2D encoders, the cache packer and the run finder is now sized by measurement in `make watchdog`, which runs the largest input of each with *two* steps per event: a pass means every step uses at most half the budget. Do the same for any new job: add its worst input to `StressTest.start()`.
+ - **M8 found that step sizes guessed from "bytecodes per loop" were 2 to 3 times too large**: a simple loop iteration costs 50 to 70 counted bytecodes, not 10 to 20. Every step of the 2D encoders, the cache packer and the run finder is now sized by measurement in `make watchdog`, which runs the largest input of each with *two* steps per event: a pass means every step uses at most half the budget. Do the same for any new job: add its worst input to `StressTest.start()`. Work on the vault goes in a `StressTest.VaultCase`: a setup in bounded steps on a RAM backend, then the measured event, done for two identical vaults.
+ - Per-byte VM loops, measured on the Forerunner 70 in 2026-10: zeroing (`Bytes.wipe`) about 15 bytecodes per byte, the UTF-8 check 20 to 29. With about 60,000 bytecodes per step (half the 255S's event), a 4 KB buffer can't be wiped or checked in one step: `Jobs.Wiper` wipes 2 KB per step, `Bytes.utf8Prefix` checks in pieces, and `SealedBox.sealKeep`/`openKeep` hand AES's padded copies to the caller's wiper.
+ - The work after a correct PIN (promoting pending entries, applying "Require PIN") is a job too (`ChangeQueue.LockJob`), run by `PinView` before it continues. In 0.9.0 it ran in the event of the last PBKDF2 step and 16 waiting "Require PIN" changes tripped the watchdog on the Forerunner 70.
- `Jobs.JobRunner` runs one step per 50 ms tick on the 512 KB watches and two on the others (`Jobs.stepsPerTick`, by app memory). `tools/gen_products.py --check` (part of `make lint`) fails if a product's `watchdogCount` doesn't match that rule.
- Drawing counts too: one `fillRectangle` per run in `onUpdate` is fine up to about 1,500 runs per 120,000 bytecodes. `RunsPainter` paints larger codes into a buffered bitmap in steps first (the Venu X1 fits a QR with 8,000 runs).
- `StringUtil.convertEncodedString` stops the app with an uncatchable "System Error" on invalid UTF-8; `try` doesn't help. Decode untrusted bytes with `Bytes.toUtf8`, which validates first.