Repository navigation
Address attestation QA findings - #6247
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
peachbits
left a comment
There was a problem hiding this comment.
Non-blocking: the CHANGELOG entries for the first three commits all landed in the last one, and the enUS.json string landed in the rates commit while its en_US.ts source is in the logs commit.
There was a problem hiding this comment.
Claude Code Review
Claude Code Review is paused for this repository. To reconnect it, an admin of this repository's GitHub organization (or the account owner, for personal repositories) who can also manage your Claude organization's Code Review settings needs to re-link GitHub in Code Review settings. This is a one-time step.
Tip: disable this comment in your organization's Code Review settings.
|
Not changed in this push. Moving the CHANGELOG lines and the |
4221be7 to
acbab39
Compare
peachbits
left a comment
There was a problem hiding this comment.
All three threads check out at acbab39. One note for landing: autosquash drops the fixup's message, so the squashed commit would keep the original body, which still says it fetches "once more on the first token" and describes the per-launch flag. Reword that body when squashing.
The clock warning only fired from the attestation handshake, so a launch that ran no handshake (attestation unsupported, or in failure backoff) never showed it, while the signed key request failed with a 401 on every launch the device clock was wrong. Carry the status and the HTTP Date header of a non-OK key response on a typed error, and feed a 401's Date header into the same once-per-day warning. An error response is not served from an HTTP cache, so its Date header is a current reading of the server clock.
The rates server stamps each current rate with its own clock. The app compared that stamp against the device clock to decide whether a rate was current or historical, so a device clock set more than an hour ahead filed every current rate as yesterday's rate. Cached rates then expired and no fiat value could be shown. Read the server's time from the Date response header and compare against that, falling back to the device clock when the header is missing or unreadable.
The logs server refuses any log dated more than five minutes from its own clock and answers 400 with the body 'Time Out of Sync'. The app dropped that body and showed only the status code, which reads as a server fault. Recognize the refusal and tell the user to fix the device clock instead.
A signed key request that goes out before the attestation handshake has a token is answered from the default layer, which has no Paybis or Simplex keys. That answer was written to the cache and nothing fetched again, so the next launch warm-started without those providers. QA hit this on launches where the handshake had to re-enroll its key or was rate limited and only succeeded on a retry. When a request goes out with no token, subscribe to the attestation engine and fetch again once a token arrives, writing the answer to the cache for the next launch. The subscription stays until a token-carrying answer is cached, so a refetch that fails is tried again at the next token. One refetch runs at a time. The running keys are not swapped. The cache records whether its request carried a token, and an answer to a request without one no longer replaces an attested entry younger than 3 days. A launch that misses the attestation budget on a device that still attests (slow handshake, rate limit) used to cache the default payload at once, so closing the app before the retry landed still cost the next launch its partner keys. The same check covers two requests in flight at once. The architecture doc describes the late-token rules as built.
|
Reworded the squashed commit body to describe the cache-side token check and the retained late-token subscription, and dropped the per-launch flag wording. |
acbab39 to
a211ee9
Compare
Description
Asana task
Fixes the failures QA reported against the attestation and key-delivery test builds.
Dateheader to the same check.Dateheader.The rates and Export Logs defects predate the attestation work and behave the same on
master. QA found them while testing the clock warning.Testing
keysStore,keysServer,attestation,ExchangeRateActions(getServerNow), and a newLogActionssuite.attestedfield, and an entry stamped four days in the future: each replaced by the unattested answer.Not covered
CountryListModal.tsxis identical tomaster. With no saved region it lists the phone's region setting first and waits for a pick. It has never selected a country automatically, so the QA step that expected that was corrected.CHANGELOG
Does this branch warrant an entry to the CHANGELOG?
Dependencies
none
Requirements
If you have made any visual changes to the GUI. Make sure you have:
Test evidence
3e760dfRefresh cached keys when a token arrives late
2026-10-07
🪓 silenced the two handshake clock checks locally so only the refused key fetch could raise the warning
1. 🪓 clock warning from refused key fetch
2. rates shown with clock two days ahead
3. export logs clock message with clock ahead
4. clock warning in live session after clock jump
Note
Medium Risk
Changes boot-time key caching and partner plugin availability, plus shared clock-skew UX; mistakes could affect buy/sell providers or first-launch key tiers, though runtime keys are not swapped mid-session.
Overview
Fixes QA issues around wrong device clocks and slow or late device attestation affecting partner keys, rates, and support tooling.
Attestation / remote keys: When the initial key fetch runs without a token, the app now subscribes for a late attestation token and refetches once, caching the attested payload for the next launch without hot-swapping running keys. Cache entries record
attestedandfetchedAt; unattested answers no longer overwrite a recent attested cache (3-day hold). A 401 on the signed key fetch passes the responseDateinto the existing clock-skew warning so launches that never run a handshake still alert the user.Exchange rates: Current vs historical rates are aged against the rates server clock from the
Dateheader (getServerNow), so a device clock set far ahead no longer hides all fiat values.Export logs: A 400 with body
Time Out of Syncsurfaces a dedicatedLogsClockErrormessage instead of a generic status error.Docs (
CONFIG_KEYS_ARCHITECTURE.md), types, locales, and unit tests cover the new cache rules, errors, and behaviors.Reviewed by Cursor Bugbot for commit a211ee9. Bugbot is set up for automated code reviews on this repo. Configure here.