Skip to content

fleet-queue(client): HOME unset/empty makes home() empty — broker socket, token, and worker signal paths all anchor at the filesystem root #5673

Open

Description

@dezren39

Problem

In the fleet-queue client (pkgs/fleet/crates/fleet-queue/src/client.rs, the repo-queue binary every fleet agent uses to enqueue / claim / signal), the home helper treats a missing or empty HOME as the empty string:

// client.rs:31-33
fn home() -> String {
    std::env::var("HOME").unwrap_or_default()
}

Every path the client derives is a format!("{}/...", home()), so with HOME unset or empty each one anchors at the filesystem root instead of the user's home:

  • client.rs:56 — session-proxy socket: /.cache/laptop-agent/broker.sock
  • client.rs:76 — direct-broker marker: /.config/repo-queue/broker-url
  • client.rs:95 — direct-broker token: /.config/queue-broker/token
  • client.rs:148 — session-proxy payload token_file: /tools/queue-broker-token (the laptop-side proxy is told to read the broker token from the root of its filesystem)
  • client.rs:218 — auto-start fallback program: /tools/laptop-agent-broker.py
  • client.rs:223 — spawn_broker does create_dir_all("/.cache/laptop-agent") and opens /.cache/laptop-agent/broker.log there
  • client.rs:1221 — cmd_signal's default signal path: /workspace/goals/keep-the-four-repos-healthy/hidden_files/repo-queue-signal.json — the file that wakes the queue worker lands at the root-anchored path, not the goal workspace, so the signal silently never reaches the worker

Same crate, secondary sites: the brokers handle unset loudly but let the empty half through — queue_broker.rs:592 and secrets_broker.rs:192 use std::env::var("HOME").expect("HOME unset"), so HOME="" yields the root-anchored token paths /.config/queue-broker/token / /.config/secrets-broker/token; secrets_broker.rs:45 reads the Bitwarden access token from {home}/.config/bitwarden/access-token with the same empty-home shape.

Evidence

Code read at current main 2db40a34e0 (via gh api raw reads; the laptop SSH route was down during this run, so no binary probe — the behaviour follows deterministically from the constructions above: env::var("HOME") errs on unset and returns "" on empty, unwrap_or_default() maps both to "", and format!("{home}/.cache/...") with home == "" is the root-anchored path shown).

Contrast inside this repo, i.e. the class is known and the fix shape exists:

Why it matters

repo-queue is invoked from cron jobs, systemd units, and agent shells — exactly the contexts where HOME is most often unset or empty. In that state the client does not fail: it connects to (or tries to spawn) a broker at root-anchored paths, reads a broker URL / token from files the operator never wrote, and writes the worker-wake signal to a path no watcher reads. The failure presents as a silently idle queue or a "cannot connect to session proxy" error pointing nowhere near the cause. If a root-anchored /.config/repo-queue/broker-url or token file ever exists (e.g. created by a root-run invocation), a later user-level client would silently trust it.

Acceptance criteria

  • The client's home resolution treats an empty HOME as unset, and with HOME unset/empty every verb either fails loudly naming HOME or resolves the real home another way — one rule, shared with (or matching) fleet-config's non_empty_path approach.
  • With HOME unset/empty, no fleet-queue verb reads, writes, creates, or spawns at a root-anchored path (/.cache/..., /.config/..., /tools/..., /workspace/...).
  • The brokers (queue_broker.rs, secrets_broker.rs) treat empty HOME the same as unset at the token-file / access-token sites.
  • Regression tests pin both shapes (unset and empty) for at least the broker socket path, the direct-broker token path, and the signal path.
  • Behaviour with HOME set is unchanged: existing fleet-queue tests stay green and the paths resolve exactly as today.

Activity

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    task/triageQueue packet kind: verify, reproduce, and route this item
    source/creatorFiled by the new-issue-creator job
    priority/normalOrdinary priority (the default)
    queue/queuedHas a queued task in the Supabase agent queue
    app/fleetpkgs/fleet multicall binary + platform crates
    on Nov 4, 2026
  2. dezren39 commented on Nov 4, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed

  3. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 5, 2026
  4. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  5. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

    Triage findings (task 9755, verified 2026-11-05)

    Confirmed — still present at current main. Fresh gh api contents reads this run:

    • pkgs/fleet/crates/fleet-queue/src/client.rs (1332 lines): lines 31–32 are exactly fn home() -> String { std::env::var("HOME").unwrap_or_default() }, and line 56 still derives the broker socket as format!("{}/.cache/laptop-agent/broker.sock", home()) — so HOME unset or empty anchors every derived path at the filesystem root, as issue fleet-queue(client): HOME unset/empty makes home() empty — broker socket, token, and worker signal paths all anchor at the filesystem root #5673 describes.
    • pkgs/fleet/crates/fleet-queue/src/queue_broker.rs line 592: std::env::var("HOME").expect("HOME unset") — loud on unset, silent on empty.
    • pkgs/fleet/crates/fleet-queue/src/secrets_broker.rs line 192: same expect("HOME unset"). One nuance vs the issue text: line 45 uses std::env::var("HOME").ok()? rather than the same construction — the effect for empty HOME is the same (an empty string passes through and the access-token path anchors at root), so the acceptance criteria cover it unchanged.

    Issue #5673 is OPEN with no hard-stop labels (held, user/owned, do-not-merge, do-not-auto-edit all absent) and no matching PR. The in-repo fix shape from #5473 (fleet-config's non_empty_path) is the reference the acceptance criteria already name.

    Routing: enqueued as task 9770 (small_fix, repo-health-code-pilot) carrying the issue's acceptance criteria verbatim. Issue #5673 stays open for task 9770.

  6. 123 remaining items

  7. dezren39 commented on Nov 6, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · handed off

  8. added
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    status/parkedDeliberately paused with a recorded resume condition
    and removed
    queue/claimedQueue worker lifecycle state
    on Nov 6, 2026
  9. dezren39 commented on Nov 6, 2026

    @dezren39
    MemberAuthor

    Lane B (code-b) claimed task 9770 for issue #5673. Execution-lane assignment returned opencode (§1b), so this task is handed off to the opencode claimant — checkpointed handed_off and parked 1200s for the claimant to launch the bound session. Issue verified OPEN with no hard-stop labels (held / user/owned / do-not-merge / do-not-auto-edit).

  10. dezren39 commented on Nov 6, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · handed off

  11. dezren39 commented on Nov 6, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · handed off

  12. added
    queue/claimedQueue worker lifecycle state
    and removed
    status/parkedDeliberately paused with a recorded resume condition
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    on Nov 6, 2026
  13. dezren39 commented on Nov 6, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  14. dezren39 commented on Nov 6, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · PR opened

    • Agent: queue worker (repo-worker-code), OpenChamber scheduled lane 7b47536b-c162-444c-be8a-3a9538cc4cb5
    • Session / ID: task 9770; session ses_e5e4fe9e7daffeLVY2gO7CETIQ
    • Task: shared HOME resolver now rejects unset/empty before client dispatch; both brokers use the resolver and secrets lookup skips invalid HOME paths.
    • Verification: all-target fleet-queue tests passed (38/38); formatter and diff checks passed.
    • PR: fix(fleet-queue): reject unset and empty HOME (#5673) #6478 — CI status will be checked fresh; task will be completed if green or parked if still pending.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/fleetpkgs/fleet multicall binary + platform crateskind/bugSomething isn't working (prefixed form of the classic bug label)priority/normalOrdinary priority (the default)queue/claimedQueue worker lifecycle statesource/creatorFiled by the new-issue-creator jobsource/design-architectFiled by the repo design architect jobstatus/in-progressQueue worker lifecycle statetask/triageQueue packet kind: verify, reproduce, and route this itemwork/assignedQueue worker lifecycle state

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions