Repository navigation
fleet-search(client): home_dir() falls back to a literal "~" when HOME is unset (and to the CWD when HOME is empty) — a planted ./~/.config/atlas-search/client.json token is loaded and submitted, and a planted service.json marker flips seat routing to standalone #5918
Description
fleet-search(client): home_dir() falls back to a literal "" when HOME is unset (and to the CWD when HOME is empty) — a planted .//.config/atlas-search/client.json token is loaded and submitted, and a planted service.json marker flips seat routing to standalone
Evidence
pkgs/fleet/crates/fleet-search/src/client.rs:53-57 (laptop primary @ 102bfa6):
fn home_dir() -> PathBuf {
std::env::var_os("HOME")
.map(PathBuf::from)
.unwrap_or_else(|| PathBuf::from("~"))
}PathBuf::from("~") is a relative path — nothing expands a tilde — and an empty HOME maps to PathBuf::from(""), whose joins are plain CWD-relative. Every consumer of home_dir() therefore resolves under the process's current working directory when HOME is unset or empty:
client_token()—client.rs:84-87: reads the bearer token from~/.config/atlas-search/client.json(unset) or.config/atlas-search/client.json(empty).serving_host_marker()—client.rs:65-69, used byresolve_route(src/lib.rs:323): existence of~/.local/state/atlas-search/service.jsonis the seat signal that routes searches standalone instead of via-service.ensure_sandbox_forward()—client.rs:163: probes~/tools/laptop-ssh.shunder the same bogus root.
Verified this run on the laptop with the installed fleet binary (behaviour matches the code above; scratch dirs under /tmp/probe-search-home/):
- HOME unset, clean CWD:
fleet search probequery --via-service→no service client token (set ATLAS_SEARCH_TOKEN or create ~/.config/atlas-search/client.json)— the error names a literal-~relative path. - HOME unset, planted
./~/.config/atlas-search/client.jsoncontaining{"token": "PROBE-PLANTED-TOKEN"}: the token was loaded and submitted to the live service —service at http://127.0.0.1:18760 rejected the job submit: HTTP 401 (unauthorized: invalid client token). A file planted in the working directory became the client's bearer credential. - HOME empty (
HOME=), clean CWD: the token error names.config/atlas-search/client.json(plain CWD-relative); with that file planted (PROBE-PLANTED-TOKEN2) it was likewise loaded and submitted (401 from the service). - HOME unset, planted
./~/.local/state/atlas-search/service.json, no routing flag: the search went straight to standalone (no via-service token attempt at all), while the identical run in a clean CWD (control) attempted via-service first. A planted empty file flips the Q3 seat routing.
Why it matters
fleet search is run from arbitrary working directories (agent sessions, scripts, shells inside checked-out repos). When HOME is unset or empty — cron/systemd-style environments, env -i, scrubbed agent shells — whoever controls the CWD controls (a) which bearer token the client presents to the search service: a planted token is a credential-substitution / confused-deputy path, and a planted valid token file (e.g. dropped into a shared checkout) would be silently used; and (b) the seat routing, via a zero-byte marker file. The sibling fallbacks were already ruled wrong in this codebase — fleet-config's "." fallback (#5737, open) and fleet-queue's empty-string home() (#5673, open) — but fleet-search's literal-"~" variant is a third, distinct mechanism in a third crate, and it is the only one whose fallback file is a credential that gets transmitted.
Acceptance criteria
- With
HOMEunset or empty,fleet searchnever resolves the client config, the service marker, or the sandbox-forward probe against the CWD (no literal-~directory, no bare.config/...): it fails closed with a clear error naming the missingHOME, or resolves through a non-CWD source of truth — one behaviour chosen, documented in the module doc, and pinned by tests. - A test plants
./~/.config/atlas-search/client.jsonand./.config/atlas-search/client.jsonin a scratch CWD withHOMEunset and empty in turn, and shows the planted token is never read/submitted in either case. - A test shows a planted
./~/.local/state/atlas-search/service.jsonwithHOMEunset does not flip routing to standalone. - With
HOMEset normally, token resolution, the marker check, and routing behave exactly as before (existing behaviour pinned by a control test). - Sibling consistency is considered in the fix note: fleet-config: HOME unset/empty falls back to "." — config, state dir, and broker socket resolve CWD-relative, and a planted ./fleet.toml loads #5737 (fleet-config) and fleet-queue(client): HOME unset/empty makes home() empty — broker socket, token, and worker signal paths all anchor at the filesystem root #5673 (fleet-queue) are the same ruling in other crates; this issue covers only
pkgs/fleet/crates/fleet-search.
Related
- fleet-config: HOME unset/empty falls back to "." — config, state dir, and broker socket resolve CWD-relative, and a planted ./fleet.toml loads #5737 — fleet-config
home_dir()"."fallback (open, distinct crate/mechanism) - fleet-queue(client): HOME unset/empty makes home() empty — broker socket, token, and worker signal paths all anchor at the filesystem root #5673 — fleet-queue client
home()empty-string fallback (open, distinct crate/mechanism)
Activity
developing-today commentedon Nov 5, 2026
CODE-1597
dezren39 commentedon Nov 5, 2026
🤖 Agent note · state: filed
dezren39 commentedon Nov 5, 2026
🤖 Agent note · state: done
pkgs/fleet/crates/fleet-search/src/client.rs:53— among its six sites, including the client-token and serving-host-marker paths. My pre-filing dedup queries missed it (the matching search's result arrived after the filing). The verification evidence gathered for this issue (planted token loaded and submitted to the live service, HTTP 401; planted marker flipping seat routing vs control) has been posted on issue atlas-search(fleet-search): HOME unset/empty resolves state/config/token paths relative to the CWD (literal ~ dir) #5640 so nothing is lost.dezren39 commentedon Nov 5, 2026
🤖 Agent note · done
102bfa62ba7c90cc8e7f3b68d5ad27a555c4c1d9:pkgs/fleet/crates/fleet-search/src/client.rshome_dir()still readsvar_os("HOME").map(PathBuf::from).unwrap_or_else(|| PathBuf::from("~"))— a literal relative~when HOME is unset, andPathBuf::from("")(CWD-relative joins) when HOME is empty. All three consumers verified in the same read:client_token(),serving_host_marker(), andensure_sandbox_forward(). No open PR covers issue fleet-search(client): home_dir() falls back to a literal "~" when HOME is unset (and to the CWD when HOME is empty) — a planted ./~/.config/atlas-search/client.json token is loaded and submitted, and a planted service.json marker flips seat routing to standalone #5918 or issue atlas-search(fleet-search): HOME unset/empty resolves state/config/token paths relative to the CWD (literal ~ dir) #5640 (checked this run). This matches the issue's own laptop probe evidence (planted token loaded and submitted; planted marker flipped routing to standalone).dezren39 commentedon Nov 5, 2026
🤖 Agent note · done
client.rssite, and the creator already posted this issue's planted-token/marker evidence on issue atlas-search(fleet-search): HOME unset/empty resolves state/config/token paths relative to the CWD (literal ~ dir) #5640. Triage task 9806 itself completed as triaged (CONFIRMED at main102bfa62); no separate work should start from issue fleet-search(client): home_dir() falls back to a literal "~" when HOME is unset (and to the CWD when HOME is empty) — a planted ./~/.config/atlas-search/client.json token is loaded and submitted, and a planted service.json marker flips seat routing to standalone #5918.