Repository navigation
Description
Problem
searchpath.Resolve expands any entry starting with ~ into the caller's own home directory. A ~name entry — which in every shell and in the usual ~user convention names that user's home — is silently rewritten to a subdirectory of the caller's home, and a directory literally named ~scratch relative to the working directory can never be named at all.
Evidence (verified this run on main 211aa58f)
pkgs/mcpx/internal/searchpath/searchpath.go:117-125(absolute):strings.HasPrefix(path, "~")matches every leading~, thenfilepath.Join(home, strings.TrimPrefix(path, "~"))splices the remainder under the caller's home. There is no distinction between~,~/…and~name[/…].- Probe executed this run on the laptop (
~/git/fleet/probe-2026-10-28-lanea-searchpath/,searchpath.gocopied verbatim, sha25692c048ed…; log in the goal'shidden_files/probe-2026-10-28-laneA-searchpath/probe.log), withHOME=/home/testhome:~alice/scripts→/home/testhome/alice/scripts~nosuchuser/scripts→/home/testhome/nosuchuser/scripts~scratch→/home/testhome/scratch- Controls correct:
~/scripts→/home/testhome/scripts,~→/home/testhome
- The resolved list is what actually gets searched:
internal/cli/scripts.go:58(scriptPath, from thepaths.scriptssetting /MCPX_PATHS_SCRIPTS),internal/cli/scripts.go:164(PlaceholderFiles,paths.placeholders), andinternal/daemon/consumer.go:145(recipeDirs) all pass configured entries throughResolve. searchpath_test.gohas no~test at all, so neither the correct control cases nor the~namemisresolution are pinned.Describe()(searchpath.go:259) renders the already-rewritten absolute path, so the "why is it not finding my script" diagnostic confidently shows a directory the user never wrote.
Why it matters
Configured search paths are user-typed configuration. A user who writes ~alice/scripts (a shared/team account's scripts) is silently searched in a lookalike directory under their own home instead — scripts are not found, and if $HOME/alice/scripts happens to exist, the wrong scripts are found and run with no hint why. Silent misresolution in a path that decides which code executes is worse than an error.
Acceptance criteria
-
~and~/…keep expanding to the caller's home (existing correct behaviour, now pinned by tests). - A
~name[/…]entry is not resolved under the caller's home: triage pins the rule — expand to that user's home where the platform supports it, or leave the entry unexpanded/refuse it with a clear diagnostic — and the chosen rule is documented atabsolute. - Regression tests in
internal/searchpathcover~alice/scripts, a~namefor a nonexistent user,~, and~/scripts. -
Describe()output for a~nameentry matches the locationsFind/Listactually search. - Existing
internal/searchpath,internal/cliandinternal/daemontests keep passing.
Activity
developing-today commentedon Oct 28, 2026
CODE-682
dezren39 commentedon Oct 28, 2026
🤖 Agent note · filed
dezren39 commentedon Oct 28, 2026
Cross-link: companion issue filed this run in the same package — #1704 (List reports a shadowed name as ambiguous although Find resolves it). Different defect (List/Find disagreement vs this issue's absolute()
name misresolution); both verified by the same laptop probe (/git/fleet/probe-2026-10-28-lanea-searchpath/).14 remaining items
dezren39 commentedon Oct 31, 2026
🤖 Agent note · parked
dezren39 commentedon Oct 31, 2026
🤖 Agent note · parked
dezren39 commentedon Oct 31, 2026
🤖 Agent note · picked up
fix(mcpx): searchpath expands only ~ and ~/ — ~name stays a literal r…
dezren39 commentedon Oct 31, 2026
🤖 Agent note · done
6bee50a89a4aabd31ddb571c749a6b4f01e4a23b. CI run 41176621901 all PASS (lint, plugin tests, stress PR-changed tests, final budget; docs build PASS); Codex gate clean (0 review threads). searchpath now expands only~and~/...;~namestays a literal relative entry.fix(mcpx): source abs() expands home only for bare ~ and ~/ (#2988) (#…