Skip to content

beta: debug report through the share sheet; transfers settle in seconds - #1107

Merged
cryptskii merged 3 commits into
mainfrom
cryptskii/eager-darwin-1668e4
Oct 2, 2026
Merged

cryptskii merged 3 commits into
mainfrom
cryptskii/eager-darwin-1668e4

Conversation

@cryptskii

@cryptskii cryptskii commented Oct 2, 2026 •

Copy link
Copy Markdown
Collaborator

Two fixes from tonight's hardware run.

1. The debug report goes out through the share sheet, with the app's log

The diagnostics screen's Download button built a blob: link and clicked it. An Android WebView ignores that, so the button did nothing and then showed "Diagnostics downloaded". The report it would have saved also held no log of the wallet itself, only the bridge's method names and payload sizes.

Share report replaces it. The native side writes the report and opens the Android share sheet with it (a FileProvider over the report's cache directory only). The report holds:

  • the app version and install time, the device model, the Android version and the supported ABIs;
  • what the app measured: session, identity and architecture as before, plus each contact's send state as Rust derives it (ready, or blocked and why) and its chain tip;
  • the app's own log, from disk and from logcat's current buffer;
  • the bridge log.

The app log on disk. logcat keeps only minutes of the app's log. App.onCreate starts a logcat child that writes this app's lines to files/diagnostics/app.log:

  • Rust (DSM_RUST) and every other tag at Info;
  • the WebView compositor's per-frame tags (View, GPUAUX, BufferQueueProducer) silenced;
  • rotated at 1 MB across 8 files.

The report includes those files oldest first, then logcat's current buffer with the compositor's lines filtered out. It also says whether the on-disk log is running.

2. A two-phone transfer settles in seconds

On two A16s with both apps open, Alice could not send back to Carol for 48 s after Carol's transfer had arrived. Alice's own log shows her acceptance delivered at 14:37:14, her send refused at 14:37:37 (Waiting for the peer to finalize a transfer you received), and Carol's certificate applied at 14:38:02.

The causes:

  • the poller ran every 5 s while settling, and every 60 s otherwise, even with the app on screen;
  • wallet.send refused at once while the certificate was on its way.

The changes:

  • Settling: while settlement work is outstanding, the poller runs every 2 s. That covers a sender awaiting the acceptance, a recipient owing its reply or awaiting the certificate, and a certificate not yet at quorum.
  • App on screen: with nothing settling, the poller runs every 5 s instead of every 60 s.
  • Sending: when the recipient's certificate for a transfer this device accepted is still outstanding, wallet.send syncs every 1.5 s for up to 20 s before the send-ready authority decides.

The finality barrier itself is unchanged: a certificate that never arrives still refuses the send.

Verification

  • Settlement tests: the bilateral finality tests pass against local storage nodes: harness, r1 (role reversal), r2a (still refused, now after the wait) and r2b. cargo clippy -p dsm_sdk --all-targets -D warnings and cargo fmt are clean.
  • Frontend: type-check and lint are clean, and the diagnostics suites pass (23 tests). The real-code guard passes.
  • Kotlin: not compiled locally (no Android SDK here). This PR's Android build is its first compile.
  • On a phone: nothing has run on a phone yet.
  • Share path: no unit test, since testing it would need a new test double, which the real-code guard refuses.
  • Code map: the Rust change will need its intent pins refreshed.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Y4wDTToHmJfkYYJvMKXt3u

claude added 2 commits October 2, 2026 18:42
…the app's log

The diagnostics screen's Download built a blob: link and clicked it. An
Android WebView ignores that, so the button did nothing and then said
"Diagnostics downloaded". The report it would have saved also held no
log of the wallet itself, only the bridge's method names and sizes.

Share report now has the native side write the report and open the
Android share sheet with it (FileProvider over the report's cache
directory), so a tester can send it by mail, chat or Drive. The report
holds the app and device versions; what the app measured, now with each
contact's send state as Rust derives it (ready, or blocked and why) and
its chain tip; the app's own log; and the bridge log.

logcat keeps minutes of the app's log, and a report is often asked for
long after the failure. App.onCreate starts a logcat child that keeps
this app's lines (Rust at Info, every other tag at Info, the WebView
compositor's per-frame tags silenced) on disk, rotated at 1 MB across 8
files. The report includes those files oldest first and logcat's current
buffer with the compositor's lines filtered out, and says whether the
on-disk log is running.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y4wDTToHmJfkYYJvMKXt3u
…cate before refusing a send

On two A16s, both apps open, a send back to the sender was refused for
48 s after the money had moved: the recipient's poller ran at 5 s while
settling and 60 s otherwise, the sender at 5 s, and wallet.send refused
at once while the sender's finality certificate was still on its way.

- Settlement work (a sender awaiting the acceptance, a recipient owing
  its reply or awaiting the certificate, a certificate not yet at
  quorum) now polls every 2 s.
- With the app on screen and nothing settling, the poller runs every
  5 s instead of every 60 s, so an incoming transfer shows within that.
- wallet.send, when the recipient's certificate for a transfer this
  device accepted is still outstanding, syncs every 1.5 s for up to 20 s
  before the send-ready authority decides. The barrier is unchanged: a
  certificate that does not come still refuses the send, as before.

The bilateral finality tests pass against local storage nodes:
harness, r1 role reversal, r2a (still refused, now after the wait) and
r2b.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y4wDTToHmJfkYYJvMKXt3u
@cryptskii cryptskii changed the title diagnostics: the debug report goes out through the share sheet, with the app's log beta: debug report through the share sheet; transfers settle in seconds Oct 2, 2026

Copy link
Copy Markdown
Collaborator Author

Code map fails on 03652f3d because this PR changes Rust in dsm_sdk (inbox_poller.rs, session_manager.rs, app_router_impl.rs). That moves the intent pins for the code the evidence tests reach, so their recorded digests no longer match.

This failure is caused by this PR. The fix is the usual repin:

  1. Build the requirement map locally for this tree.
  2. Run the evidence tests the moved pins name.
  3. Repin through ci/intent_pins.py's rules, code-only.

That's in progress, and the repin will land as the next push on this branch.


Generated by Claude Code

The poller, session and wallet.send changes moved 96 pins, all code-only.
Evidence ran at 03652f3: 31 dsm lib tests, 5 dsm integration tests
(economic_admission_lifecycle, economic_lineage_register,
economic_write_set, native_reserve_wire) and 35 dsm_sdk lib tests against
local storage nodes, all passing. make requirement-map-intent: 635 pins
PINNED, 0 failing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y4wDTToHmJfkYYJvMKXt3u

Copy link
Copy Markdown
Collaborator Author

Android Instrumented Tests (managed device) failed on cf7ec496 before any test ran. Gradle's managed-device setup could not install an SDK component on the runner:

InstallFailedException: Failed to install the following SDK components:
    emulator Android Emulator

This failure isn't caused by this PR: no test body ran, and nothing in this PR touches the emulator or the SDK setup. I'll re-run the failed job once when the rest of the run finishes; GitHub refuses a re-run while the run is still going. A second failure gets treated as real.


Generated by Claude Code

@cryptskii
cryptskii merged commit f809016 into main Oct 2, 2026
43 of 44 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants