Several fields in the agent run loop are shared across UI, agent, and overlay threads without synchronization.
Findings
mAgentRunGeneration — non-volatile int, written on the UI thread and read from the agent thread in isCancelled(). AssistantActivityBackend.java:216, 3291.
- Pending-confirmation state (
mPendingActionId, related fields) — shared across UI thread, static overlay entry (:100), and agent threads with no synchronization. :3352.
OpenPhoneAgentJobScheduler.isCancelled() hardcodes false (:142-144) — background jobs cannot be stopped once started.
Fix
- Convert
mAgentRunGeneration to AtomicInteger (or make it volatile + never increment across threads).
- Guard pending-confirmation fields with a single lock or move them into an immutable snapshot object swapped via an AtomicReference.
- Wire
OpenPhoneAgentJobScheduler.isCancelled() to a real cancellation signal from the job manager.
Small, focused change — good good first issue for someone comfortable with Java concurrency.
Size: S
Several fields in the agent run loop are shared across UI, agent, and overlay threads without synchronization.
Findings
mAgentRunGeneration— non-volatileint, written on the UI thread and read from the agent thread inisCancelled().AssistantActivityBackend.java:216, 3291.mPendingActionId, related fields) — shared across UI thread, static overlay entry (:100), and agent threads with no synchronization.:3352.OpenPhoneAgentJobScheduler.isCancelled()hardcodesfalse(:142-144) — background jobs cannot be stopped once started.Fix
mAgentRunGenerationtoAtomicInteger(or make itvolatile+ never increment across threads).OpenPhoneAgentJobScheduler.isCancelled()to a real cancellation signal from the job manager.Small, focused change — good
good first issuefor someone comfortable with Java concurrency.Size: S