Skip to content

Reduce asg_client UART file-transfer ACK latency - #3501

Draft
nic-olo wants to merge 10 commits into
devfrom
cursor/asg-file-transfer-latency-bce3
Draft

Reduce asg_client UART file-transfer ACK latency#3501
nic-olo wants to merge 10 commits into
devfrom
cursor/asg-file-transfer-latency-bce3

Conversation

@nic-olo

@nic-olo nic-olo commented Jul 20, 2026

Copy link
Copy Markdown
Member

Summary

Addresses Mentra Live UART/BLE file-transfer turnaround lag vs the OEM K900Server benchmark (~1ms ACK→send / ~11ms RTT vs Mentra’s ~5ms / ~15ms).

Changes

  • RecvThread: replace Thread.sleep(5/50) poll with Os.poll (SerialReceiveWait) so inbound ACKs are noticed immediately
  • ACK fast path: detect cs_flts in onSerialRead during an active transfer and call handleFileTransferAck directly (removes dead message[0] == CMD_TYPE_PHOTO check that never matched ## frames)
  • Offload refill: schedule sendNextFilePacket on fileTransferExecutor so UART TX drain does not block RX
  • Log gating: suppress per-packet hot-path logs unless log.tag.K900BluetoothManager=VERBOSE
  • Instrumentation: FileTransferLatencyStats emits FileTransferLatency SUMMARY with ack_to_send / packet_rtt p50/p95 and packets/s
  • CI tests: fast-path routing + microbenchmark asserting fast path ≥2× slower-path; recv-wait unit tests
  • On-device harness: asg_client/scripts/bench-file-transfer-latency.sh

How to verify

# Unit tests
cd asg_client && ./gradlew :app:testDebugUnitTest --tests 'com.mentra.asg_client.io.bluetooth.managers.mentralive.internal.*'

# Compile
./scripts/check-android-compile.sh asg

# On device after a BLE photo transfer
./asg_client/scripts/bench-file-transfer-latency.sh --dump

Notes

Full packet_rtt still includes BES firmware wait (esp. 8-packet batched ACK). Mentra-owned improvement is measured by ack_to_send_*.

Open in Web Open in Cursor 

Cut Mentra-owned turnaround on the BES file-transfer hot path by replacing
the sleep-based UART poll with Os.poll, restoring a real cs_flts fast path,
offloading window refill from RecvThread, and gating per-packet logging.
Add ack_to_send/RTT instrumentation, CI microbenchmarks, and an on-device
logcat harness comparable to K900Server.

Co-authored-by: Nicolo Micheletti <michelettinik@gmail.com>
@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

📋 PR Review Helper

📱 Mobile App Build

Ready to test! (commit 6d91786)

📥 Download APK

🕶️ ASG Client Build

Ready to test! (commit 6d91786)

📥 Download ASG APK


🔀 Test Locally

gh pr checkout 3501

@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

PR Agent Orchestrator State

{
  "cycle": 14,
  "fixRound": 2,
  "totalReviewerRuns": 14,
  "consecutiveNoNewReviews": 6,
  "openFindings": [],
  "resolvedFindings": [],
  "nitFindings": [
    {
      "id": "8f4aff",
      "fingerprint": "asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/k900bluetoothmanager.java:b9f06b9d113b",
      "source": "standards",
      "severity": "nit",
      "file": "asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java",
      "line": 81,
      "message": "New member field 'fileTransferLatencyStats' omits the AGENTS.md-documented mCamelCase 'm' prefix; consistent with the file's pre-existing style (not a regression), so nit only.",
      "status": "open",
      "introducedCycle": 3,
      "lastSeenCycle": 3
    },
    {
      "id": "7d3a2d",
      "fingerprint": ".git:f19ca6c99a2b",
      "source": "standards",
      "severity": "nit",
      "file": ".git",
      "line": 0,
      "message": "PR commits are authored by 'Cursor Agent <cursoragent@cursor.com>'. No prohibited AI Co-Authored-By trailer or 'Generated with' line is present (co-author is a human), but per AGENTS.md commits should reflect the human author; prefer human as primary author.",
      "status": "open",
      "introducedCycle": 3,
      "lastSeenCycle": 3
    },
    {
      "id": "102fe4",
      "fingerprint": "asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/k900bluetoothmanager.java:b9ccd802bf75",
      "source": "depth",
      "severity": "nit",
      "file": "asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java",
      "line": 81,
      "message": "currentFileTransfer and fileTransferLatencyStats are non-volatile but are now read/written across RecvThread (handleFileTransferAck/onAckSeen) and fileTransferExecutor (sendNextFilePacket/sendFilePacketAt). Worst case is a swallowed NPE in the pump during an already-aborting transfer or a dropped stats sample; consider marking currentFileTransfer volatile now that the pump runs off RecvThread.",
      "status": "open",
      "introducedCycle": 4,
      "lastSeenCycle": 4
    },
    {
      "id": "047551",
      "fingerprint": "asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/mentralive/internal/serialreceivewait.java:b7c651c0eb15",
      "source": "depth",
      "severity": "nit",
      "file": "asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/mentralive/internal/SerialReceiveWait.java",
      "line": 47,
      "message": "PollWait relies on closeSerial() to wake a blocked Os.poll (interrupt may not); prompt RecvThread shutdown/reopen depends on the fd being closed, otherwise it can linger up to POLL_TIMEOUT_MS (1000ms) and briefly share mReadBuf with a newly started RecvThread. Safe with current stop()/reopen() but worth documenting.",
      "status": "open",
      "introducedCycle": 4,
      "lastSeenCycle": 4
    },
    {
      "id": "bd4980",
      "fingerprint": "asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/k900bluetoothmanager.java:1f477e8266e6",
      "source": "standards",
      "severity": "nit",
      "file": "asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java",
      "line": 81,
      "message": "fileTransferLatencyStats is accessed from RecvThread and the file-transfer executor but is not volatile; consider marking the field reference volatile for cross-thread visibility (matches existing non-volatile currentFileTransfer pattern, so not a regression).",
      "status": "open",
      "introducedCycle": 7,
      "lastSeenCycle": 7
    },
    {
      "id": "d2df71",
      "fingerprint": "asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/mentralive/internal/filetransferlatencystats.java:448f06719e59",
      "source": "standards",
      "severity": "nit",
      "file": "asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/mentralive/internal/FileTransferLatencyStats.java",
      "line": 16,
      "message": "Internal tunable MAX_SAMPLES (and POLL_TIMEOUT_MS in SerialReceiveWait) are private static final in-class; asg_client/AGENTS.md prefers tunables in AsgConstants.java. Low priority since these are internal implementation details.",
      "status": "open",
      "introducedCycle": 7,
      "lastSeenCycle": 7
    },
    {
      "id": "02bd19",
      "fingerprint": "asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/k900bluetoothmanager.java:94b7d7438e69",
      "source": "standards",
      "severity": "nit",
      "file": "asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java",
      "line": 81,
      "message": "AGENTS.md prescribes mCamelCase member vars; fileTransferLatencyStats omits the m prefix, but matches the file's established non-prefixed convention so not actionable in isolation.",
      "status": "open",
      "introducedCycle": 7,
      "lastSeenCycle": 7
    }
  ],
  "frozenPair": [
    "bugbot",
    "standards"
  ],
  "phase": "convergence",
  "status": "budget_exhausted",
  "lastPair": [],
  "stagnationFixRounds": 0,
  "lastOpenCount": 0,
  "fingerprintReopenCounts": {},
  "mutedFingerprints": []
}

@github-actions

Copy link
Copy Markdown
Contributor

bugbot run

@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

🤖 PR Agent Review — cycle 14

✅ No blocking findings · 0 blocking · 7 nits
Reviewers this cycle: none

No model reviews ran this cycle.

Updated automatically by the PR Agent Orchestrator each review cycle. Nits do not block merge.

Expand the CI slow path to include the AsgClientService preview and
json.toString() logging costs that Mentra used to pay on every cs_flts,
so the 2x fast-path assertion stays meaningful under Robolectric.

Co-authored-by: Nicolo Micheletti <michelettinik@gmail.com>
@blacksmith-sh

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

bugbot run

github-actions Bot and others added 3 commits July 20, 2026 05:14
Fold ack→send / packet RTT / packets-per-sec into the existing PAYLOAD /
TRANSFER section (and PIPELINE FINISHED one-liner) so the K900Server
comparison metrics ship with the rest of the photo timing report.
@github-actions

Copy link
Copy Markdown
Contributor

bugbot run

@github-actions

Copy link
Copy Markdown
Contributor

PR Agent Handoff

Exit reason: Clean handoff — CI green, no blocking findings, models have no further reviews.

Metric Value
Fix rounds 2
Review cycles 7
Consecutive no-new-review cycles 2

CI status

Check Status Conclusion
MentraOS ASG Client Build completed success

Remaining blocking findings

None

Nits (informational)

  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) New member field 'fileTransferLatencyStats' omits the AGENTS.md-documented mCamelCase 'm' prefix; consistent with the file's pre-existing style (not a regression), so nit only.
  • (.git) PR commits are authored by 'Cursor Agent cursoragent@cursor.com'. No prohibited AI Co-Authored-By trailer or 'Generated with' line is present (co-author is a human), but per AGENTS.md commits should reflect the human author; prefer human as primary author.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) currentFileTransfer and fileTransferLatencyStats are non-volatile but are now read/written across RecvThread (handleFileTransferAck/onAckSeen) and fileTransferExecutor (sendNextFilePacket/sendFilePacketAt). Worst case is a swallowed NPE in the pump during an already-aborting transfer or a dropped stats sample; consider marking currentFileTransfer volatile now that the pump runs off RecvThread.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/mentralive/internal/SerialReceiveWait.java) PollWait relies on closeSerial() to wake a blocked Os.poll (interrupt may not); prompt RecvThread shutdown/reopen depends on the fd being closed, otherwise it can linger up to POLL_TIMEOUT_MS (1000ms) and briefly share mReadBuf with a newly started RecvThread. Safe with current stop()/reopen() but worth documenting.

Humans merge when ready. Agents do not auto-merge. Label agent-resume to re-run the loop after new commits.

@github-actions

Copy link
Copy Markdown
Contributor

PR Agent Handoff

Exit reason: Clean handoff — CI green, no blocking findings, models have no further reviews.

Metric Value
Fix rounds 2
Review cycles 8
Consecutive no-new-review cycles 0

CI status

Check Status Conclusion
MentraOS ASG Client Build completed success

Remaining blocking findings

None

Nits (informational)

  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) New member field 'fileTransferLatencyStats' omits the AGENTS.md-documented mCamelCase 'm' prefix; consistent with the file's pre-existing style (not a regression), so nit only.
  • (.git) PR commits are authored by 'Cursor Agent cursoragent@cursor.com'. No prohibited AI Co-Authored-By trailer or 'Generated with' line is present (co-author is a human), but per AGENTS.md commits should reflect the human author; prefer human as primary author.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) currentFileTransfer and fileTransferLatencyStats are non-volatile but are now read/written across RecvThread (handleFileTransferAck/onAckSeen) and fileTransferExecutor (sendNextFilePacket/sendFilePacketAt). Worst case is a swallowed NPE in the pump during an already-aborting transfer or a dropped stats sample; consider marking currentFileTransfer volatile now that the pump runs off RecvThread.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/mentralive/internal/SerialReceiveWait.java) PollWait relies on closeSerial() to wake a blocked Os.poll (interrupt may not); prompt RecvThread shutdown/reopen depends on the fd being closed, otherwise it can linger up to POLL_TIMEOUT_MS (1000ms) and briefly share mReadBuf with a newly started RecvThread. Safe with current stop()/reopen() but worth documenting.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) fileTransferLatencyStats is accessed from RecvThread and the file-transfer executor but is not volatile; consider marking the field reference volatile for cross-thread visibility (matches existing non-volatile currentFileTransfer pattern, so not a regression).
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/mentralive/internal/FileTransferLatencyStats.java) Internal tunable MAX_SAMPLES (and POLL_TIMEOUT_MS in SerialReceiveWait) are private static final in-class; asg_client/AGENTS.md prefers tunables in AsgConstants.java. Low priority since these are internal implementation details.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) AGENTS.md prescribes mCamelCase member vars; fileTransferLatencyStats omits the m prefix, but matches the file's established non-prefixed convention so not actionable in isolation.

Humans merge when ready. Agents do not auto-merge. Label agent-resume to re-run the loop after new commits.

Dev stopgap so BLE/miniapp captures persist the sensor JPEG on-glasses
even when the request sends save=false, for quality comparison pulls.
@github-actions

Copy link
Copy Markdown
Contributor

PR Agent Handoff

Exit reason: Budget exhausted — fix or review cycle cap reached.

Metric Value
Fix rounds 2
Review cycles 9
Consecutive no-new-review cycles 1

CI status

Check Status Conclusion
MentraOS ASG Client Build in_progress

Remaining blocking findings

None

Nits (informational)

  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) New member field 'fileTransferLatencyStats' omits the AGENTS.md-documented mCamelCase 'm' prefix; consistent with the file's pre-existing style (not a regression), so nit only.
  • (.git) PR commits are authored by 'Cursor Agent cursoragent@cursor.com'. No prohibited AI Co-Authored-By trailer or 'Generated with' line is present (co-author is a human), but per AGENTS.md commits should reflect the human author; prefer human as primary author.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) currentFileTransfer and fileTransferLatencyStats are non-volatile but are now read/written across RecvThread (handleFileTransferAck/onAckSeen) and fileTransferExecutor (sendNextFilePacket/sendFilePacketAt). Worst case is a swallowed NPE in the pump during an already-aborting transfer or a dropped stats sample; consider marking currentFileTransfer volatile now that the pump runs off RecvThread.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/mentralive/internal/SerialReceiveWait.java) PollWait relies on closeSerial() to wake a blocked Os.poll (interrupt may not); prompt RecvThread shutdown/reopen depends on the fd being closed, otherwise it can linger up to POLL_TIMEOUT_MS (1000ms) and briefly share mReadBuf with a newly started RecvThread. Safe with current stop()/reopen() but worth documenting.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) fileTransferLatencyStats is accessed from RecvThread and the file-transfer executor but is not volatile; consider marking the field reference volatile for cross-thread visibility (matches existing non-volatile currentFileTransfer pattern, so not a regression).
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/mentralive/internal/FileTransferLatencyStats.java) Internal tunable MAX_SAMPLES (and POLL_TIMEOUT_MS in SerialReceiveWait) are private static final in-class; asg_client/AGENTS.md prefers tunables in AsgConstants.java. Low priority since these are internal implementation details.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) AGENTS.md prescribes mCamelCase member vars; fileTransferLatencyStats omits the m prefix, but matches the file's established non-prefixed convention so not actionable in isolation.

Humans merge when ready. Agents do not auto-merge. Label agent-resume to re-run the loop after new commits.

@github-actions

Copy link
Copy Markdown
Contributor

PR Agent Handoff

Exit reason: Budget exhausted — fix or review cycle cap reached.

Metric Value
Fix rounds 2
Review cycles 10
Consecutive no-new-review cycles 2

CI status

Check Status Conclusion
MentraOS ASG Client Build completed success

Remaining blocking findings

None

Nits (informational)

  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) New member field 'fileTransferLatencyStats' omits the AGENTS.md-documented mCamelCase 'm' prefix; consistent with the file's pre-existing style (not a regression), so nit only.
  • (.git) PR commits are authored by 'Cursor Agent cursoragent@cursor.com'. No prohibited AI Co-Authored-By trailer or 'Generated with' line is present (co-author is a human), but per AGENTS.md commits should reflect the human author; prefer human as primary author.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) currentFileTransfer and fileTransferLatencyStats are non-volatile but are now read/written across RecvThread (handleFileTransferAck/onAckSeen) and fileTransferExecutor (sendNextFilePacket/sendFilePacketAt). Worst case is a swallowed NPE in the pump during an already-aborting transfer or a dropped stats sample; consider marking currentFileTransfer volatile now that the pump runs off RecvThread.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/mentralive/internal/SerialReceiveWait.java) PollWait relies on closeSerial() to wake a blocked Os.poll (interrupt may not); prompt RecvThread shutdown/reopen depends on the fd being closed, otherwise it can linger up to POLL_TIMEOUT_MS (1000ms) and briefly share mReadBuf with a newly started RecvThread. Safe with current stop()/reopen() but worth documenting.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) fileTransferLatencyStats is accessed from RecvThread and the file-transfer executor but is not volatile; consider marking the field reference volatile for cross-thread visibility (matches existing non-volatile currentFileTransfer pattern, so not a regression).
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/mentralive/internal/FileTransferLatencyStats.java) Internal tunable MAX_SAMPLES (and POLL_TIMEOUT_MS in SerialReceiveWait) are private static final in-class; asg_client/AGENTS.md prefers tunables in AsgConstants.java. Low priority since these are internal implementation details.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) AGENTS.md prescribes mCamelCase member vars; fileTransferLatencyStats omits the m prefix, but matches the file's established non-prefixed convention so not actionable in isolation.

Humans merge when ready. Agents do not auto-merge. Label agent-resume to re-run the loop after new commits.

nic-olo added 3 commits July 20, 2026 17:45
Flatten IMG_*/base.jpg captures from the glasses camera package dir into
mobile/Camera_comparison/new_focus for local quality comparison.
Delete IMG_/VID_/BUFFER_ capture dirs and related ASG media folders via
adb so local quality-comparison pulls can start from a clean gallery.
Replace mapfile with portable listing and a single remote wipe command so
bun wipe:glasses-photos works on stock macOS /bin/bash.
@github-actions

Copy link
Copy Markdown
Contributor

PR Agent Handoff

Exit reason: Budget exhausted — fix or review cycle cap reached.

Metric Value
Fix rounds 2
Review cycles 11
Consecutive no-new-review cycles 3

CI status

Check Status Conclusion
Mobile App Quality Checks pending
Mobile App Android Build pending
MentraOS ASG Client Build pending

Remaining blocking findings

None

Nits (informational)

  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) New member field 'fileTransferLatencyStats' omits the AGENTS.md-documented mCamelCase 'm' prefix; consistent with the file's pre-existing style (not a regression), so nit only.
  • (.git) PR commits are authored by 'Cursor Agent cursoragent@cursor.com'. No prohibited AI Co-Authored-By trailer or 'Generated with' line is present (co-author is a human), but per AGENTS.md commits should reflect the human author; prefer human as primary author.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) currentFileTransfer and fileTransferLatencyStats are non-volatile but are now read/written across RecvThread (handleFileTransferAck/onAckSeen) and fileTransferExecutor (sendNextFilePacket/sendFilePacketAt). Worst case is a swallowed NPE in the pump during an already-aborting transfer or a dropped stats sample; consider marking currentFileTransfer volatile now that the pump runs off RecvThread.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/mentralive/internal/SerialReceiveWait.java) PollWait relies on closeSerial() to wake a blocked Os.poll (interrupt may not); prompt RecvThread shutdown/reopen depends on the fd being closed, otherwise it can linger up to POLL_TIMEOUT_MS (1000ms) and briefly share mReadBuf with a newly started RecvThread. Safe with current stop()/reopen() but worth documenting.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) fileTransferLatencyStats is accessed from RecvThread and the file-transfer executor but is not volatile; consider marking the field reference volatile for cross-thread visibility (matches existing non-volatile currentFileTransfer pattern, so not a regression).
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/mentralive/internal/FileTransferLatencyStats.java) Internal tunable MAX_SAMPLES (and POLL_TIMEOUT_MS in SerialReceiveWait) are private static final in-class; asg_client/AGENTS.md prefers tunables in AsgConstants.java. Low priority since these are internal implementation details.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) AGENTS.md prescribes mCamelCase member vars; fileTransferLatencyStats omits the m prefix, but matches the file's established non-prefixed convention so not actionable in isolation.

Humans merge when ready. Agents do not auto-merge. Label agent-resume to re-run the loop after new commits.

@github-actions

Copy link
Copy Markdown
Contributor

PR Agent Handoff

Exit reason: Budget exhausted — fix or review cycle cap reached.

Metric Value
Fix rounds 2
Review cycles 12
Consecutive no-new-review cycles 4

CI status

Check Status Conclusion
Mobile App Quality Checks in_progress
Mobile App Android Build in_progress
MentraOS ASG Client Build in_progress

Remaining blocking findings

None

Nits (informational)

  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) New member field 'fileTransferLatencyStats' omits the AGENTS.md-documented mCamelCase 'm' prefix; consistent with the file's pre-existing style (not a regression), so nit only.
  • (.git) PR commits are authored by 'Cursor Agent cursoragent@cursor.com'. No prohibited AI Co-Authored-By trailer or 'Generated with' line is present (co-author is a human), but per AGENTS.md commits should reflect the human author; prefer human as primary author.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) currentFileTransfer and fileTransferLatencyStats are non-volatile but are now read/written across RecvThread (handleFileTransferAck/onAckSeen) and fileTransferExecutor (sendNextFilePacket/sendFilePacketAt). Worst case is a swallowed NPE in the pump during an already-aborting transfer or a dropped stats sample; consider marking currentFileTransfer volatile now that the pump runs off RecvThread.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/mentralive/internal/SerialReceiveWait.java) PollWait relies on closeSerial() to wake a blocked Os.poll (interrupt may not); prompt RecvThread shutdown/reopen depends on the fd being closed, otherwise it can linger up to POLL_TIMEOUT_MS (1000ms) and briefly share mReadBuf with a newly started RecvThread. Safe with current stop()/reopen() but worth documenting.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) fileTransferLatencyStats is accessed from RecvThread and the file-transfer executor but is not volatile; consider marking the field reference volatile for cross-thread visibility (matches existing non-volatile currentFileTransfer pattern, so not a regression).
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/mentralive/internal/FileTransferLatencyStats.java) Internal tunable MAX_SAMPLES (and POLL_TIMEOUT_MS in SerialReceiveWait) are private static final in-class; asg_client/AGENTS.md prefers tunables in AsgConstants.java. Low priority since these are internal implementation details.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) AGENTS.md prescribes mCamelCase member vars; fileTransferLatencyStats omits the m prefix, but matches the file's established non-prefixed convention so not actionable in isolation.

Humans merge when ready. Agents do not auto-merge. Label agent-resume to re-run the loop after new commits.

@github-actions

Copy link
Copy Markdown
Contributor

PR Agent Handoff

Exit reason: Budget exhausted — fix or review cycle cap reached.

Metric Value
Fix rounds 2
Review cycles 13
Consecutive no-new-review cycles 5

CI status

Check Status Conclusion
Mobile App Quality Checks in_progress
Mobile App Android Build in_progress
MentraOS ASG Client Build in_progress

Remaining blocking findings

None

Nits (informational)

  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) New member field 'fileTransferLatencyStats' omits the AGENTS.md-documented mCamelCase 'm' prefix; consistent with the file's pre-existing style (not a regression), so nit only.
  • (.git) PR commits are authored by 'Cursor Agent cursoragent@cursor.com'. No prohibited AI Co-Authored-By trailer or 'Generated with' line is present (co-author is a human), but per AGENTS.md commits should reflect the human author; prefer human as primary author.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) currentFileTransfer and fileTransferLatencyStats are non-volatile but are now read/written across RecvThread (handleFileTransferAck/onAckSeen) and fileTransferExecutor (sendNextFilePacket/sendFilePacketAt). Worst case is a swallowed NPE in the pump during an already-aborting transfer or a dropped stats sample; consider marking currentFileTransfer volatile now that the pump runs off RecvThread.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/mentralive/internal/SerialReceiveWait.java) PollWait relies on closeSerial() to wake a blocked Os.poll (interrupt may not); prompt RecvThread shutdown/reopen depends on the fd being closed, otherwise it can linger up to POLL_TIMEOUT_MS (1000ms) and briefly share mReadBuf with a newly started RecvThread. Safe with current stop()/reopen() but worth documenting.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) fileTransferLatencyStats is accessed from RecvThread and the file-transfer executor but is not volatile; consider marking the field reference volatile for cross-thread visibility (matches existing non-volatile currentFileTransfer pattern, so not a regression).
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/mentralive/internal/FileTransferLatencyStats.java) Internal tunable MAX_SAMPLES (and POLL_TIMEOUT_MS in SerialReceiveWait) are private static final in-class; asg_client/AGENTS.md prefers tunables in AsgConstants.java. Low priority since these are internal implementation details.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) AGENTS.md prescribes mCamelCase member vars; fileTransferLatencyStats omits the m prefix, but matches the file's established non-prefixed convention so not actionable in isolation.

Humans merge when ready. Agents do not auto-merge. Label agent-resume to re-run the loop after new commits.

@github-actions

Copy link
Copy Markdown
Contributor

PR Agent Handoff

Exit reason: Budget exhausted — fix or review cycle cap reached.

Metric Value
Fix rounds 2
Review cycles 14
Consecutive no-new-review cycles 6

CI status

Check Status Conclusion
Mobile App Quality Checks completed success
Mobile App Android Build in_progress
MentraOS ASG Client Build completed success

Remaining blocking findings

None

Nits (informational)

  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) New member field 'fileTransferLatencyStats' omits the AGENTS.md-documented mCamelCase 'm' prefix; consistent with the file's pre-existing style (not a regression), so nit only.
  • (.git) PR commits are authored by 'Cursor Agent cursoragent@cursor.com'. No prohibited AI Co-Authored-By trailer or 'Generated with' line is present (co-author is a human), but per AGENTS.md commits should reflect the human author; prefer human as primary author.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) currentFileTransfer and fileTransferLatencyStats are non-volatile but are now read/written across RecvThread (handleFileTransferAck/onAckSeen) and fileTransferExecutor (sendNextFilePacket/sendFilePacketAt). Worst case is a swallowed NPE in the pump during an already-aborting transfer or a dropped stats sample; consider marking currentFileTransfer volatile now that the pump runs off RecvThread.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/mentralive/internal/SerialReceiveWait.java) PollWait relies on closeSerial() to wake a blocked Os.poll (interrupt may not); prompt RecvThread shutdown/reopen depends on the fd being closed, otherwise it can linger up to POLL_TIMEOUT_MS (1000ms) and briefly share mReadBuf with a newly started RecvThread. Safe with current stop()/reopen() but worth documenting.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) fileTransferLatencyStats is accessed from RecvThread and the file-transfer executor but is not volatile; consider marking the field reference volatile for cross-thread visibility (matches existing non-volatile currentFileTransfer pattern, so not a regression).
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/mentralive/internal/FileTransferLatencyStats.java) Internal tunable MAX_SAMPLES (and POLL_TIMEOUT_MS in SerialReceiveWait) are private static final in-class; asg_client/AGENTS.md prefers tunables in AsgConstants.java. Low priority since these are internal implementation details.
  • (asg_client/app/src/main/java/com/mentra/asg_client/io/bluetooth/managers/K900BluetoothManager.java) AGENTS.md prescribes mCamelCase member vars; fileTransferLatencyStats omits the m prefix, but matches the file's established non-prefixed convention so not actionable in isolation.

Humans merge when ready. Agents do not auto-merge. Label agent-resume to re-run the loop after new commits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants