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
5.1 KiB
Final Review Report: Job 26b5444e (PR #47 / Issue #42 Skills Link)
1. Review Identity & Metadata
- Loop ID:
loop-20261004T043243Z-baf133 - Job ID:
26b5444e - Reviewer: agy (session:
herdr:reviewer-agy-01) - Base Commit:
6af4a796b1bdce3b2e929b7a45a8a22d66b36855(main, v4.8.3) - Head Commit:
e1ed2708d835d712f5f3a9dfd51b8f66ca1ac447(1 commit) - Tree Hash:
2f781e0db4df9a3082b4f55e69c42118868b18a1 - Verification Path:
/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261004T043243Z-baf133/1 - Git Status: Clean (working tree clean, no uncommitted changes)
- Whitespace Check (
git diff base...HEAD --check): Clean (0 errors)
2. Commit Audit (base..head)
Commit e1ed270: test(issue-42): the .claude/skills check accepts both local layouts
Diff summary:
tests/test_issue42_skill_blocks.py: Modifiedtest_claude_skills_link_resolves_to_agents_skills()to support both local.claude/skillslayouts:- A single symlink pointing directly to
.agents/skills(link.is_symlink()). - A local directory containing individual symlinks for each skill in
SKILL_NAMES.
- A single symlink pointing directly to
Product Code Modifications: None (0 changes to .sh or .py product code).
3. Review Item Verification & Empirical Testing
Item 1: Behavior Across Both Layouts & Edge Cases
Empirical tests were executed inside the verification path across all layouts and boundary cases (with temporary .claude structures removed after verification):
- Absent
.claude/skills(Worktree default):- Behavior: Skipped with
pytest.skip(".claude/skills is untracked; absent in a worktree"). - Result: PASS (skipped cleanly).
- Behavior: Skipped with
- Single Symlink Layout (
.claude/skills -> .agents/skills):- Tested:
ln -s ../.agents/skills .claude/skills - Behavior:
link.is_symlink()evaluates toTrue, verifieslink.resolve() == SKILLS.resolve(). - Result: PASS.
- Tested:
- Per-Skill Directory Layout (Control plane / Main checkout):
- Tested:
.claude/skills/containing symlinks for all 8multi-agent-mux-*skills plus helper links (lib.sh,lib_py). - Behavior: Verifies
entry.exists()andentry.resolve() == (SKILLS / skill).resolve()for every skill inSKILL_NAMES. - Result: PASS.
- Tested:
- Missing Skill in Directory Layout (Negative test):
- Tested: Omitted
multi-agent-mux-stopsymlink. - Behavior: Fails immediately with
AssertionError: .claude/skills/multi-agent-mux-stop is missing. - Result: PASS (correctly caught).
- Tested: Omitted
- Misdirected Symlink Target (Negative test):
- Tested: Pointed
multi-agent-mux-stoptomulti-agent-mux-create. - Behavior: Fails with
AssertionError: .claude/skills/multi-agent-mux-stop -> .../multi-agent-mux-create. - Result: PASS (correctly caught).
- Tested: Pointed
- Broken Symlink (Negative test):
- Tested: Pointed
multi-agent-mux-createto nonexistent target. - Behavior:
entry.exists()returnsFalse, failing withAssertionError: .claude/skills/multi-agent-mux-create is missing. - Result: PASS (correctly caught).
- Tested: Pointed
- Regular File at
.claude/skills(Negative test):- Tested: Created plain file
.claude/skills. - Behavior: Child path lookup on regular file evaluates
entry.exists() == False, failing cleanly withAssertionError: .claude/skills/multi-agent-mux-create is missing. - Result: PASS (correctly caught).
- Tested: Created plain file
- Static Completeness of
SKILL_NAMES:SKILL_NAMESis defined from.agents/skills/multi-agent-mux-*/SKILL.mdand enforced bytest_inventory_covers_eight_skills(len == 8). Cannot be empty.
Item 2: Strictness & Flexibility Assessment
- Appropriate Flexibility: Allows additional local symlinks or files within
.claude/skills(such aslib.shorlib_py) without triggering false alarms, reflecting that Claude Code only registers subdirectories containingSKILL.md. - Appropriate Strictness: Unconditionally requires that all 8 canonical skills are present and resolve to their exact corresponding
.agents/skills/<skill>directories.
Item 3: Scope & Diff Inspection
- Exactly 1 file modified:
tests/test_issue42_skill_blocks.py(+10, -1). - No changes to product scripts, library code, or documentation.
- No version bump.
4. Test Suite Execution Results
Executed in verification worktree (/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261004T043243Z-baf133/1) with --basetemp=/tmp/pytest-pr47:
| Test Suite | Result | Duration |
|---|---|---|
tests/test_issue42_skill_blocks.py |
31 passed, 1 skipped* | 0.07 s |
tests/test_version_consistency.py |
3 passed | 0.22 s |
* Note: test_claude_skills_link_resolves_to_agents_skills skipped as expected in worktrees lacking untracked .claude/skills; empirical tests confirmed passing under both layouts.
5. Conclusion
PR #47 cleanly and robustly supports both local layouts of .claude/skills, preventing false failures on the main checkout while maintaining strict integrity verification across all canonical skills.
[VERDICT: PASS]