diff --git a/plugins/kyberforge/skills/agent-audit/scripts/validate.sh b/plugins/kyberforge/skills/agent-audit/scripts/validate.sh index 0339939..5ebe829 100755 --- a/plugins/kyberforge/skills/agent-audit/scripts/validate.sh +++ b/plugins/kyberforge/skills/agent-audit/scripts/validate.sh @@ -147,16 +147,22 @@ def find_apm_package_root(apm_yml_path): return False def detect_scope(start_dir): + home = os.path.expanduser('~') current = os.path.abspath(start_dir) while True: apm_yml = os.path.join(current, 'apm.yml') if os.path.isfile(apm_yml) and find_apm_package_root(apm_yml): return 'plugin', current + # $HOME is the user-scope boundary — checked before the .git test + # below, so a dotfiles-managed $HOME (yadm, chezmoi bare-repo, etc.) + # can't shadow user scope by being its own .git repo. + if current == home: + return 'user', home if os.path.isdir(os.path.join(current, '.git')): return 'project', current parent = os.path.dirname(current) if parent == current: - return 'user', os.path.expanduser('~') + return 'user', home current = parent agent_dir = os.path.dirname(agent_file) diff --git a/plugins/kyberforge/skills/agent-audit/tests/validate.bats b/plugins/kyberforge/skills/agent-audit/tests/validate.bats index 4bb1a93..7ed3568 100644 --- a/plugins/kyberforge/skills/agent-audit/tests/validate.bats +++ b/plugins/kyberforge/skills/agent-audit/tests/validate.bats @@ -68,6 +68,30 @@ EOF refute_output --partial "FAIL" } +@test "user scope: \$HOME being a dotfiles .git repo does not shadow user scope" { + local fake_home="$TMPDIR/fakehome" + mkdir -p "$fake_home/.git" "$fake_home/.claude/agents" "$fake_home/.copilot/agents" + cat > "$fake_home/.claude/agents/my-agent.md" < "$fake_home/.copilot/agents/my-agent.agent.md" <