Repository navigation
Description
fleet-config: a relative XDG_CONFIG_HOME / XDG_STATE_HOME is used verbatim — config and state resolve CWD-relative and a planted ./fleet.toml loads even with HOME set
Summary
fleet-config treats an empty XDG base as invalid (#5473), but a non-empty relative XDG base is used verbatim. The XDG Base Directory specification requires relative values in these variables to be considered invalid and ignored. As a result, with HOME set correctly, XDG_CONFIG_HOME=relcfg makes the config path relcfg/fleet/fleet.toml — relative to the process's current working directory — and Config::load() loads a fleet.toml planted in the working directory. XDG_STATE_HOME relative likewise puts the state dir (and the materialized shims dir under it) in the CWD.
This is a distinct trigger from the two filed siblings: #5473 (closed) covered empty XDG values; #5737 (open) covers HOME unset/empty falling back to ".". Neither covers a non-empty relative XDG base with HOME present and correct.
Evidence (file:line, origin/main @ 967fb22; pkgs/fleet unchanged between laptop HEAD and origin/main)
pkgs/fleet/crates/fleet-config/src/lib.rs:211-223— the crate's own comment: "the XDG base-directory spec treats an empty base as invalid; taking one literally here would turn the config file, the state dir, and the broker socket into CWD-relative paths (issue 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)".non_empty_pathfilters only the empty case;env_pathreturns any non-empty value, relative included.pkgs/fleet/crates/fleet-config/src/lib.rs:252-263—file_path_from:let base = xdg_config_home.unwrap_or_else(|| home.join(".config")); base.join("fleet").join("fleet.toml")— a relative base stays relative.pkgs/fleet/crates/fleet-config/src/lib.rs:442-445—state_dir_fromhas the same shape forXDG_STATE_HOME;shims_dir()isstate_dir()/shims.- The XDG spec (Base Directory Specification): "If an implementation encounters a relative path in any of these variables it should consider the path invalid and ignore it."
Verification (this run, laptop, real fleet-config crate)
Probe ~/git/fleet/probe-fleet-config-xdg-rel (path-depends on the real fleet-config crate; run from a scratch dir containing a planted relcfg/fleet/fleet.toml with [domains] planted = false):
HOME=/home/user XDG_CONFIG_HOME=relcfg XDG_STATE_HOME=relstate(FLEET_CONFIG unset):file_path=relcfg/fleet/fleet.tomlstate_dir=relstate/fleetplanted_enabled=false— the planted CWD config was loaded (an unknown domain defaults to enabled;falsecan only come from the planted file)queue_enabled=true(control domain untouched)
- Control, absolute XDG bases: paths anchor at the given absolute dirs; planted file ignored (
planted_enabled=true). - Control, no XDG vars:
file_path=/home/user/.config/fleet/fleet.toml,state_dir=/home/user/.local/state/fleet; planted file ignored.
Why it matters
- A fleet process launched with a relative XDG base (a templated systemd unit, a wrapper script exporting
XDG_CONFIG_HOME=.config, a container entrypoint) silently reads its configuration — including the[domains]disable lever the crate docs call an incident lever — from whoever controls its working directory: the exact planted-config hazard 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 for the empty spelling. - The state/shims dirs landing in the CWD means two processes in different directories keep different state and different PATH shims, with no error anywhere.
Acceptance criteria
- A relative
XDG_CONFIG_HOMEorXDG_STATE_HOMEis treated as unset (ignored, per the XDG spec), exactly as an empty one is after 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; resolution falls back to the HOME-anchored default. - A planted
./<relative-base>/fleet/fleet.tomlin the working directory is never loaded when HOME is set and the XDG base is relative. - Pinning tests cover relative XDG bases for
file_pathandstate_diralongside the existing empty-value tests (env_paths_ignore_empty_values_and_resolve_under_home, lib.rs:577). - Behavior with absolute XDG bases and with HOME set is otherwise unchanged; existing fleet-config tests stay green.
- Out of scope:
FLEET_CONFIGitself (an explicit per-file override a user may deliberately spell relative) and the HOME-unset fallback (fleet-config: HOME unset/empty falls back to "." — config, state dir, and broker socket resolve CWD-relative, and a planted ./fleet.toml loads #5737).
Activity
developing-today commentedon Nov 5, 2026
CODE-1908
dezren39 commentedon Nov 5, 2026
🤖 Agent note · filed
dezren39 commentedon Nov 5, 2026
🤖 Agent note · handed off
62 remaining items
dezren39 commentedon Nov 6, 2026
🤖 Agent note · handed off
queue/queued,task/fix, andtask/small-fix; claimed/in-progress labels were cleared.dezren39 commentedon Nov 6, 2026
🤖 Agent note · done
dezren39 commentedon Nov 6, 2026
🤖 Agent note · picked up
dezren39 commentedon Nov 6, 2026
🤖 Agent note · done