The .claude/skills check accepts both local layouts and fails on a dangling link. Review: round 1 (@e1ed270) claude agy grok PASS, codex NOT PASS (a dangling top-level link was skipped); fixed in 150b493; round 2 4/4 PASS. Reports and the round-2 identity sidecars go to .agents/reports/<session>/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
4.0 KiB
Review: PR #47 @ e1ed270
- Role: Reviewer (grok)
- Identity: base
6af4a796b1bdce3b2e929b7a45a8a22d66b36855, heade1ed2708d835d712f5f3a9dfd51b8f66ca1ac447, tree2f781e0db4df9a3082b4f55e69c42118868b18a1, 1 commit, clean worktree - Verified read-only at
/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261004T043243Z-baf133/1, except temporary.claude/skillslayouts created there and removed afterward. Main stayed at6af4a79. The control-plane.claude/skillswas only read. git diff --stat 6af4a79..HEAD:tests/test_issue42_skill_blocks.py, +10/−1.git diff --checkis 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/<name>. 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 eightmulti-agent-mux-*/SKILL.mddirectories) must exist under.claude/skillsand resolve to.agents/skills/<skill>(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, thenlink / skilldoes not exist, so the test fails. lib.shandlib_pybeside the eight links do not fail the test. Neither has aSKILL.md(lib.shis a file;lib_pyis the package). Claude Code loads a skill from a directory that containsSKILL.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 ownSKILL.mdwould 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/skillsitself is skipped.Path.exists()is false for a dangling symlink, and that check runs beforeis_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_NAMESwould make the directory branch pass without checking any entry. The name list is the eightSKILL.mdparents, andtest_inventory_covers_eight_skillsin 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.shandlib_py:32 passed in 0.06s.
[VERDICT: PASS]