Skip to content

fleet-config: empty XDG env vars resolve to CWD-relative paths (a planted ./fleet/fleet.toml is loaded), and a relative FLEET_BROKER_SOCKET bypasses under-HOME resolution #5473

Closed

Description

@dezren39

fleet-config: empty XDG env vars resolve to CWD-relative paths (a planted ./fleet/fleet.toml is loaded), and a relative FLEET_BROKER_SOCKET bypasses under-HOME resolution

Evidence (verified this run, laptop probe against the real crate @ main 3b3df1b)

Probe: ~/git/fleet/probe-fleetconfig-env on the laptop — a binary crate with a path dependency on pkgs/fleet/crates/fleet-config, driving the public API with controlled env vars (HOME=/tmp/fakehome123):

  • A — XDG_CONFIG_HOME="": Config::file_path() returns "fleet/fleet.toml" — a relative path. (pkgs/fleet/crates/fleet-config/src/lib.rs: file_path() maps var_os("XDG_CONFIG_HOME") straight into PathBuf::from with no empty check; XDG base-directory spec says an empty value is invalid and must be treated as unset.)
  • B — with a planted ./fleet/fleet.toml in the working directory ([domains] queue = false), Config::load() loads that file: domain_enabled("queue") == false. So from any directory containing a stray fleet/fleet.toml, fleet silently takes its config — including domain disables, broker socket, and token-file path — from the CWD instead of the user's ~/.config/fleet/fleet.toml.
  • C — control, XDG_CONFIG_HOME unset: file_path() is /tmp/fakehome123/.config/fleet/fleet.toml and the planted file is ignored (queue_enabled=true).
  • E — same flaw in state_dir(): XDG_STATE_HOME="" returns relative "fleet", so the state/shims dirs also land in the CWD.
  • D — broker_socket(): a relative FLEET_BROKER_SOCKET (e.g. .cache/laptop-agent/broker.sock, the default's own spelling) is returned as-is, CWD-relative, while the config-file value and the compiled default both go through resolve_under_home — despite the field doc "relative paths resolve under $HOME". The same operator spelling therefore names different sockets depending on which source supplied it. Control: env unset → /tmp/fakehome123/.cache/laptop-agent/broker.sock.

Why it matters

fleet-config is the one place fleet configuration resolves, and its crate docs make a loud-error / no-silent-surprises contract (#5460 just enforced it for typos). Empty-string env vars are a routine artifact (systemd units, env -i wrappers, templated exports that expand to nothing), and here they quietly relocate the config file, the state dir, and — via a relative env socket — the broker endpoint to whatever directory the process happens to start in. The CWD-planted config case is the sharp edge: config content (domain disables = the incident lever, socket and token-file paths) becomes directory-dependent.

Acceptance criteria

  • Empty XDG_CONFIG_HOME / XDG_STATE_HOME are treated as unset (fall back to ~/.config / ~/.local/state); empty FLEET_CONFIG likewise falls through to the XDG path instead of naming an empty path.
  • A relative FLEET_BROKER_SOCKET env value resolves under $HOME, exactly like the config-file and default values.
  • Regression tests pin: empty-XDG file/state paths are the HOME-based absolutes, and the env socket spelling .cache/laptop-agent/broker.sock resolves to the same path as the default.
  • cargo test -p fleet-config green (laptop or CI; no builds on the sandbox).

Activity

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    task/small-fixQueue packet kind: bounded fix with reproduction and targeted tests
    source/creatorFiled by the new-issue-creator job
    on Nov 4, 2026
  2. developing-today commented on Nov 4, 2026

    @developing-today
    Contributor
  3. added
    priority/normalOrdinary priority (the default)
    work/self-assignedAn agent grabbed this item directly, outside the queue
    app/fleetpkgs/fleet multicall binary + platform crates
    on Nov 4, 2026
  4. dezren39 commented on Nov 4, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed

    • Agent: new-issue-creator job (lane A, slug new-issue-creator-code-a)
    • Session / ID: cron job new-issue-creator-code-a, run 2026-11-04T13:39Z
    • Found via: filed this run
    • Task: fleet-config env path resolution — empty XDG vars yield CWD-relative config/state paths (a planted ./fleet/fleet.toml is loaded) and a relative FLEET_BROKER_SOCKET bypasses under-HOME resolution. Verified with a laptop probe against the real crate; guarded self-solve this run (trivial, small, low-risk).
    • Expectation: effort/xs — fix + pinning tests, PR merged this run.
    • Links: probe ~/git/fleet/probe-fleetconfig-env (laptop)
  5. dezren39 commented on Nov 4, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    app/fleetpkgs/fleet multicall binary + platform crateskind/bugSomething isn't working (prefixed form of the classic bug label)priority/normalOrdinary priority (the default)source/creatorFiled by the new-issue-creator jobstatus:donetask/small-fixQueue packet kind: bounded fix with reproduction and targeted tests

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions