Repository navigation
Open
Labels
queue/parkedQueue task is parked (waiting on CI, time, or an event)Queue task is parked (waiting on CI, time, or an event)status/parkedDeliberately paused with a recorded resume conditionDeliberately paused with a recorded resume conditionwork/assignedQueue worker lifecycle stateQueue worker lifecycle state
Description
Coalesce queue claim flow + add a real file-transfer verb (fewer round trips, WS-C census)
Part of epic #5412. Census evidence: WS-C comment on #5701 (2026-11-04). Every sandbox↔laptop round trip costs ~200–600 ms warm, so round-trip COUNT is the lever until/unless the multiplexed-tunnel work lands.
Round-trip census today (code + logs)
| Operation | Transport round trips | Wall (measured) |
|---|---|---|
Single trivial exec (laptop-agent.py exec -- true) |
1 (unix to session proxy + 1 pooled-tunnel HTTP request) | wall 346–719 ms; trip p50 369 ms |
fleet queue claim (one claim) |
1 (call("/claim") → one broker_roundtrip → one unix_roundtrip; repo-queue crate crates/repo-queue/src/main.rs cmd_claim/call) |
~1 trip ≈ 0.3–0.6 s warm |
| Claimant launch flow (claim + lane + bind) | 3 separate CLI invocations = 3 round trips (cmd_lane, cmd_bind are separate call()s) |
~1–2 s warm, ×3 failure surfaces |
Detached job to completion (run + poll loop) |
1 + N polls (poll sleeps 3 s client-side and re-requests per iteration, laptop-agent.py poll) |
grows with job length |
| Small file fetch from laptop | NO file verb exists: fetch = 1 exec round trip with base64 -w0 in a shell string (measured 301 ms wall for /etc/hostname), 1 MiB/stream cap, +33% base64 size, no resume/offsets |
1 trip + encoding overhead |
Also measured: fleet queue health took 2.1 s and 5.8 s in two live probes (vs 0.30 s in the #5701 stage-2 window) — it visibly resolves secrets ("resolved via bitwarden") plus queries, i.e. multiple internal round trips; health should be 1 lightweight trip.
Proposal
- Batch endpoint for the claim flow: queue-broker
POST /claim-flow{queue, worker, lane, session, launched_by} performing claim+lane+bind server-side (laptop-local, Supabase calls stay on the laptop) and returning the bound row. Clientfleet queue claim --bind ...uses it when session info is present; the 3 separate verbs remain for compatibility. 3 trips → 1. - Generic batch already half-exists: the daemon
/execacceptscmds: [...](exec-batch measured: 10 trivial commands in ONE trip, 483 ms wall total vs ~400 ms EACH singly). Publish this pattern to queue/secrets clients: a/batchon the session-proxy protocol that carries several service requests (mixed ports) in one frame and fans out at the broker. Client libraries coalesce independent calls made in one invocation. - File-transfer verb: daemon
GET /file?path=&off=&len=returning raw bytes (Content-Type application/octet-stream, byte-range via query — the jobs poll already proves the offset pattern) + clientlaptop-agent.py fetch PATH OUT. No base64, chunked by offset, resume = re-request from last offset. Binary framing arrives free if the multiplexed-tunnel work (sibling issue) lands; the verb is useful on today's HTTP path too. - Poll backoff:
pollinterval 3 s fixed → exponential 1 s → 10 s cap with server-side long-poll option (?wait_s=Nholds the request until state change or N s), cutting poll trips for long jobs by ~10×.
Acceptance
- Claim+lane+bind in 1 round trip (verify in trips/broker logs: exactly 1 trip id per flow).
laptop-agent.py fetchof a 5 MiB file: byte-identical (md5), no base64, trips = ceil(size/chunk) with chunk ≥ 1 MiB.- Long-job poll trips reduced ≥5× at equal completion-detection latency ≤10 s.
Metadata
Metadata
Assignees
Labels
queue/parkedQueue task is parked (waiting on CI, time, or an event)Queue task is parked (waiting on CI, time, or an event)status/parkedDeliberately paused with a recorded resume conditionDeliberately paused with a recorded resume conditionwork/assignedQueue worker lifecycle stateQueue worker lifecycle state
Activity
developing-today commentedon Nov 5, 2026
CODE-1444
dezren39 commentedon Nov 5, 2026
Triage outcome — task 10166 (2026-11-05, lane code-p)
Verdict: CONFIRMED structurally on current mains — proposal routed as two repo-scoped follow-ups (one set, tracked here). No Drew decision needed; epic #5412 is OPEN.
Fresh verification (2026-11-05): issue #5757 OPEN, labels task/triage + queue/queued only — no hard-stop labels, one tracking comment only. No duplicate: searches for claim-flow / file-transfer verb return nothing filed.
Claim-flow (code,
pkgs/fleet/crates/fleet-queue/, main04f78696ab): the client dispatchesclaim,lane, andbindas three separate commands (client.rs:1328-1330), each its owncall()— claim posts to/claim(client.rs:882) — and the broker exposes three separate routes (queue_broker.rs:/claim:382,/lane:393,/bind:402). There is no/claim-flowroute. This shift is live evidence: every task worked paid claim + lane as separate round trips. Broker/healthis a full handler (:517), consistent with the census's heavyweight-health observation (this shift's health calls also printed the bitwarden resolution line).File verb + poll (nix,
pkgs/laptop-agent/src/laptop_agent.py, current main): the daemon's GET routes are only/health,/jobs,/jobs/<id>(:420-445) — no/fileroute exists; POST offers/exec,/jobs,/jobs/<id>/kill. The client poll loop sleeps a fixed 3 s (~/tools/laptop-agent.py:281), matching the census, with nowait_slong-poll parameter on either side.Routing (cross-repo set; this issue stays the tracker):
POST /claim-flowon the queue-broker performing claim+lane+bind server-side +fleet queue claim --bindclient support; the three separate verbs remain. Acceptance = the issue's own: exactly 1 trip id per claim flow in broker logs. This is the fleet's hottest path — every queue task in every lane pays it.GET /file?path=&off=&len=(raw bytes, offset-chunked) + clientfetch(byte-identical, no base64), and poll backoff (exponential 1 s → 10 s cap) with a server-side?wait_s=Nlong-poll on the job route. Acceptance = the issue's own md5/≥5× poll-trip criteria./batch) — the daemon/execcmds:[...]batch already exists and no client need beyond the claim flow is demonstrated; revisit only if a second concrete multi-call flow appears. The lightweight-health point folds into follow-up A's broker work as a stretch item, not a separate task.agent-note:v1
{"kind": "triage", "task": 10166, "issue": 5757, "state": "done", "outcome": "confirmed_routed_two_repo_set", "evidence": "client.rs:1328-1330 three separate verbs, broker routes /claim /lane /bind separate, no /claim-flow; nix laptop_agent.py GET routes have no /file; client poll fixed sleep(3) at laptop-agent.py:281"}
dezren39 commentedon Nov 5, 2026
agent-note:v1
{"kind":"work","task":10494,"issue":5757,"state":"in_progress","outcome":"claimed","evidence":"Open issue verified; no hard-stop labels or overlapping nix implementation. Open PR #1531 is a separate persisted-meta startup fix.","branch":"queue/10494-5757-laptop-agent-file-poll","worktree":"/home/user/git/fleet/10494-5757-laptop-agent-file-poll"}
146 remaining items
dezren39 commentedon Nov 6, 2026
🤖 Agent note · handed off
dezren39 commentedon Nov 6, 2026
🤖 Agent note · handed off
opencode; handed off to the opencode claimant, which launches the bound session (attempt 12/16)dezren39 commentedon Nov 6, 2026
🤖 Agent note · handed off