#1458

Skill discovery walks past the home folder when HOME is not an ancestor of the workspace

Openaartilesopened 18d ago

fx version: 0.0.14 (macOS arm64)

What happens

The docs say project skill roots are checked "from the workspace upward, stopping before your home directory". When HOME is not an ancestor of the workspace, the walk never meets it and goes on to /. Every skill folder on the way counts as a project root, including the real home folder's .claude/skills, .agents/skills and .codex/skills.

We run fx over ACP (fx acp) as the agent of an unattended runner, and give it its own HOME inside the project (<project>/.tenaz/private/fx-home) so the user's fx settings and MCP servers are not touched. With the project under the user's home folder, fx then finds every skill the user has installed for other agents: 354 in our case.

Setting context_limits.skill_catalog_bytes to 0 keeps them out of the prompt (fx reports skill catalog omitted 354 entries … effective=0 bytes), but:

  • capability_search still returns them, and
  • the skill tool loads any of them, without a permission request, even with permission_mode: "ask".

So a session can load a skill that runs a cloud service, which an unattended local run must not do.

How to reproduce

  1. mkdir -p ~/probe && cd ~/probe && git init (any folder under your home folder that has skills in ~/.claude/skills or ~/.agents/skills).
  2. Make an isolated home with a settings file pointing at an OpenAI-compatible endpoint, for example HOME=/tmp/fx-home with /tmp/fx-home/.fx/settings.json, and "context_limits": {"skill_catalog_bytes": 0}.
  3. Run HOME=/tmp/fx-home fx acp in ~/probe, send initialize, session/new and a prompt, and have the model call capability_search (we used a scripted endpoint that returns that tool call).
  4. The result lists the skills from ~/.claude/skills and ~/.agents/skills. A following skill call with one of their names completes with the skill's content and no session/request_permission.

The same steps in a folder outside the home folder (/tmp/probe) return "skills": []. A symlink from /tmp to the project does not help: the workspace is resolved to its real path.

What we would like

Any one of these would solve it for us:

  1. Stop the upward walk at the repository root (or the workspace root) instead of only at HOME.
  2. A setting to turn off project-ancestor and user skill roots, or to list the roots fx may use.
  3. With skill_catalog_bytes: 0, leave skills out of capability_search too, and refuse skill for skills that were not advertised.

A permission request for skill in ask mode would also let a client decide, as it does for other tools.

Workarounds we found

  • Running fx with HOME set to the workspace's parent folder stops the walk, but makes fx write .fx/ into a folder that is not ours.
  • Denying reads of the skill folders above the workspace (macOS sandbox-exec) empties the list, but fx then reports that a root "could not be read … fix access to the root and reload skills", which invites the model to try.

Activity

0

No activity yet.