Skip to content

fix: use the agent-device proxy lease for remote devices - #1029

Merged
janicduplessis merged 2 commits into
mainfrom
fix/924-eas-lease-retry
Sep 24, 2026
Merged

janicduplessis merged 2 commits into
mainfrom
fix/924-eas-lease-retry

Conversation

@janicduplessis

@janicduplessis janicduplessis commented Sep 24, 2026 •

Copy link
Copy Markdown
Collaborator

Description

stim android --remote eas with a 449 MB debug APK failed at install with UNAUTHORIZED: Lease is not active (#924). agent-device heartbeats or allocates the lease once, when a command starts, and does not renew it while install uploads the artifact. Stim's generated remote profile set no leaseProvider, so agent-device used its default policy. Under that policy the client sends no TTL and the daemon applies its 60 s default (lease-registry-scope.ts). The upload took 1m47s, so the install RPC always arrived after the lease had expired. The profile is shared by --remote proxy and --remote eas on both platforms.

Solution

The profile now sets leaseProvider: 'proxy', which selects agent-device's proxy lease policy with a 5-minute TTL (connection-runtime.ts; the daemon also defaults proxy scopes to 300 s, lease-scope.ts). This is the same shape agent-device's own connect proxy writes (proxy-profile.ts). A proxy open requires leaseId, tenantId, runId, clientId and deviceKey (request-admission.ts). The profile adds clientId, set to the per-workspace scope that tenant and runId already use. install and open are proxy lease-allocating commands and resolve deviceKey from the daemon's device list for the profile platform. connect and close are lease-deferred, and alert accept reuses the lease persisted by the earlier install and open.

The upload is still not renewed, so an upload longer than about 5 minutes (roughly 1.2 GB at the 4 MB/s seen in #923) would still fail. I did not add a retry. A retry would allocate a new lease and upload again, because the daemon's upload preflight never reports a cache hit.

The proxy lease pins a deviceKey. On a self-hosted --remote proxy daemon shared by several workspaces, a second workspace that targets the same device can get a device-lease-busy error for up to 5 minutes, until the holder runs stim stop or the TTL lapses. Before this change that window was 60 s. EAS is unaffected, because each session has its own daemon.

Verified from source, at agent-device main efce352 and at v0.20.10, the version installed here: the policy selection, the 5-minute proxy TTL, the lease-deferred and proxy-allocating command sets, and that the profile schema accepts leaseProvider and clientId. The daemon's required-but-unavailable provider gate cannot refuse proxy, because proxy is not in DEFAULT_PROVIDER_RUNTIME_REQUIRED_IDS at either version (provider-device-runtimes.ts).

The remaining unverified risk is an EAS daemon configured with maxLeaseTtlMs below 300000. Allocation would then fail with INVALID_ARGS Lease ttlMs must be between ... (lease-registry-scope.ts). A proxy daemon with several devices for the profile platform fails device selection with AMBIGUOUS_MATCH, as it already does today, so that is not a regression. The real --remote eas run is still open on #924, together with the upstream issue.

Test plan

  • agent-device.test.ts: the generated profile carries leaseProvider: 'proxy' and clientId. Without them, agent-device falls back to the 60 s default lease.
  • Real stim android --remote eas --eas-profile development from a Windows host with the trailhead debug build: pending (EAS cost). Expect install and launch to succeed and the agent-device diagnostics to show lease_allocate with ttlMs: 300000.

Refs #924

The generated remote profile had no lease provider, so agent-device applied its
60 s default lease, which is not renewed while install uploads the artifact. A
449 MB APK then failed the install with Lease is not active. The profile now
sets leaseProvider proxy and the clientId proxy admission requires, which gives
a 5 minute lease for both remote backends.

Refs #924
@janicduplessis janicduplessis changed the title fix(android): warn before a remote install that outlasts the agent-device lease fix: use the agent-device proxy lease for remote devices Sep 24, 2026
@janicduplessis

Copy link
Copy Markdown
Collaborator Author

Real --remote eas run with this branch at c12ceb1, on a macOS host with agent-device 0.20.10 and eas-cli 24.7.0:

  • trailhead at 78c2b74, new EAS Android development build d8586a1a (build 9c84e29f from fix: Windows --remote eas follow-ups: doctor host gating, remote collector, autocrlf finding #923 did not match this checkout's fingerprint), APK 449,313,360 bytes
  • stim android --remote eas --eas-profile development --json exited 0: session booted in 3m16s, install 1m16s (longer than the old 60 s lease) with no Lease is not active, launch 7s, launch_verified after 13.4 s
  • the persisted connection state has leaseProvider: "proxy" and clientId. The EAS daemon allocated the proxy lease with no INVALID_ARGS ttlMs refusal, and a heartbeat about 79 s after allocation succeeded
  • stim stop stopped the EAS session, and eas simulator:get showed STOPPED afterwards

The exact ttlMs value was not captured, because agent-device 0.20.10 only writes diagnostics for failed requests.

Not covered: the Windows-host item of #924, so this PR still says Refs #924.

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.

1 participant