Skip to content

fix(gateway): drop agent-device instance pins when relaying - #1009

Open
juliusmarminge wants to merge 2 commits into
callstackincubator:mainfrom
juliusmarminge:t3
Open

juliusmarminge wants to merge 2 commits into
callstackincubator:mainfrom
juliusmarminge:t3

Conversation

@juliusmarminge

Copy link
Copy Markdown

Problem

An agent-device client reads GET /health before it names a lease, then pins that daemon's instance id on every later request in x-agent-device-instance and x-agent-device-upstream-instance. Through a gateway, RelayHostLink sends that bare /health to the first undrained capable worker. With more than one worker, the lease's worker is often a different daemon. That daemon refuses the pinned call with 409 and x-agent-device-instance-mismatch: true, the client reports "Remote daemon instance changed", and open (agent_device.lease.allocate) fails.

Reproduced with one gateway, one macOS worker serving iOS and four Linux workers serving Android: every iOS open failed. Draining the Android workers made it pass.

Fix

RelayHostLink.forward now deletes both pin headers before it relays, the same way dropInstancePins in front/host-link.ts already does for a worker's phone daemon. The module manual's gateway flow now says this.

Verification

  • New case in src/agent-device/front/relay-host-link.test.ts: a bare /health probe and a call on a lease, each sent with both pin headers, reach fleet.relay without either one. Both cases fail on main and pass with the fix: pnpm exec vitest run --project unit src/agent-device/front/relay-host-link.test.ts gives 17 passed.
  • Commit and push hooks passed (format, lint, boundaries, comment lint, test lint, typecheck, fallow, protocol-bump, docs-surface, e2e typecheck).
  • Ran the same change on a gateway fleet with the 1 iOS + 4 Android worker setup above: every lease worked, iOS and Android, with all workers connected.

🤖 Generated with Claude Code

A client reads /health before it names a lease and pins that daemon's
instance id on every later request. The gateway forwards bare requests such
as /health to whichever capable worker it finds first, so with more than one
worker the pin often names a different daemon than the lease's. That daemon
then refuses every call with 409 x-agent-device-instance-mismatch ("Remote
daemon instance changed"), and allocation fails.

Drop x-agent-device-instance and x-agent-device-upstream-instance in
RelayHostLink.forward, as a worker already does for its phone daemon.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The SDK ships no Samsung profiles, and a devices.xml profile carries no
hinge, so there was no way to lease a Samsung fold. The profile is the
SDK's pixel_fold with the Z Fold 8's screens: inner 2448x1848 (4:3),
cover 1248x1972 (16:10). It keeps pixel_fold's hw.device.name, without
which the emulator boots one flat screen with no fold states.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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