# Review: PR #47 @ e1ed270 - Role: Reviewer (grok) - Identity: base `6af4a796b1bdce3b2e929b7a45a8a22d66b36855`, head `e1ed2708d835d712f5f3a9dfd51b8f66ca1ac447`, tree `2f781e0db4df9a3082b4f55e69c42118868b18a1`, 1 commit, clean worktree - Verified read-only at `/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261004T043243Z-baf133/1`, except temporary `.claude/skills` layouts created there and removed afterward. Main stayed at `6af4a79`. The control-plane `.claude/skills` was only read. - `git diff --stat 6af4a79..HEAD`: `tests/test_issue42_skill_blocks.py`, +10/−1. `git diff --check` is clean. No product file and no version line. `.claude/` is gitignored (`.gitignore:40`). This checkout's `.claude/skills` is a real directory, not one symlink. It holds the eight `multi-agent-mux-*` links plus `lib.sh` and `lib_py`, each aimed at `../../.agents/skills/`. The old assertion `link.resolve() == SKILLS.resolve()` fails that directory. A worktree has no `.claude/skills`, so the same test skipped during the PR #46 runs. ## The two layouts `test_claude_skills_link_resolves_to_agents_skills` (`tests/test_issue42_skill_blocks.py:240-253`): - Missing path: skip (`245-246`). A worktree stays green. - The path is a symlink: it must resolve to `.agents/skills` (`247-249`). Children are not checked, because they are the repo skills. - Otherwise each name from `SKILL_NAMES` (`:22`, the eight `multi-agent-mux-*/SKILL.md` directories) must exist under `.claude/skills` and resolve to `.agents/skills/` (`250-253`). Temporary layouts in the snapshot, deleted before the end (`git status` clean, `.claude` gone): | Layout | Result | |---|---| | absent | skipped | | symlink `../.agents/skills` | passed | | symlink to `multi-agent-mux-create` only | failed at `:248` (create's path `!=` `.agents/skills`) | | directory of the eight links, plus `lib.sh` and `lib_py` | full file **32 passed** | | `multi-agent-mux-stop` linked at `multi-agent-mux-create` | failed at `:253`, and the message shows the create path | | `multi-agent-mux-resume` linked at a missing target | failed at `:252` (`is missing`) | | `.claude/skills` a regular file | failed at `:252` (`multi-agent-mux-create is missing`) | The control-plane links resolve to the same comparison: `multi-agent-mux-create` there equals `.agents/skills/multi-agent-mux-create`. Pytest was not run in that checkout. ## Edges - A regular file is not accepted. `is_symlink()` is false, then `link / skill` does not exist, so the test fails. - `lib.sh` and `lib_py` beside the eight links do not fail the test. Neither has a `SKILL.md` (`lib.sh` is a file; `lib_py` is the package). Claude Code loads a skill from a directory that contains `SKILL.md`. Those two entries are not skills, and this checkout has them, so rejecting every extra name would be too strict. The test's job is the eight repo skills. An extra untracked directory that did contain its own `SKILL.md` would not be looked at; that is a local skill outside this check. - A broken per-skill link fails `entry.exists()` (`:252`). `exists()` follows the link, so a dangling symlink is "missing" and the test fails. - A broken symlink at `.claude/skills` itself is skipped. `Path.exists()` is false for a dangling symlink, and that check runs before `is_symlink()` (`245-247`). The previous test skipped the same way. Claude Code would not load skills through that link either. A present-but-wrong root symlink, one whose target exists, still fails the resolve check. - An empty `SKILL_NAMES` would make the directory branch pass without checking any entry. The name list is the eight `SKILL.md` parents, and `test_inventory_covers_eight_skills` in the same file requires eight skills. The directory branch is not empty on this tree. ## Checks Snapshot, control-plane venv, `--basetemp` under `/tmp/adb45follow.*` (removed after each run): - No `.claude/skills`: `31 passed, 1 skipped in 0.06s`. The skip is this test. - The per-skill directory with `lib.sh` and `lib_py`: `32 passed in 0.06s`. [VERDICT: PASS]