harden: fail install verification on zero/short skill canonicals (#235)#239
Merged
Conversation
Since #228 the agent skills are the sole command surface, but recall_verify_install and `recall doctor` derived their probes from whatever canonicals existed with no lower bound — a bad npm pack, partial checkout, or an interrupt before the skill-copy step produced zero probes and install printed "All symlinks verified" over a blank surface. - lib/install-lib.sh: recall_verify_install asserts a floor — if the source tree ships skill dirs, the canonical count must match, else push a synthetic `missing` entry so verification fails red. - src/commands/doctor.ts: extract listSkillCanonicalFiles() (shared with buildSymlinkProbes) and add exported probeSkillSurface() → WARN when the install root exists with zero skill canonicals; wired into runDoctor. - tests/install/npm-pack.test.ts: assert all 9 agent-skills/<name>/SKILL.md are packed and commands/ is excluded. - tests/install/install-sentinel.test.ts: cover the Skills step in the unconditional-step guard; regression test for the empty-canonical floor. - tests/commands/doctor-skill-surface.test.ts: probeSkillSurface unit test. - CHANGELOG: [Unreleased] Fixed entry. Refs #235, #230, #228.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #235 (P1 from the #230 post-merge audit — reviewer report finding 1, the strongest-corroborated item in the set).
Problem
Since #228, the agent skills are the sole command surface. But
recall_verify_install(lib/install-lib.sh) andrecall doctor'sbuildSymlinkProbes(src/commands/doctor.ts) derived their expected-symlink list from whatever canonicals exist under~/.agents/Recall/shared/skills/with no lower bound. A bad npm pack, partial checkout, or an interrupt before_recall_copy_skill_filesproduces zero probes,missingstays empty, and install prints "All symlinks verified" over a blank surface. Pre-#230 the commands loop backstopped this; that backstop is gone.Fix (surgical — a guard + tests, no refactor)
recall_verify_installasserts a floor: if$RECALL_REPO_DIR/agent-skillsships skill dirs, the canonical count under$RECALL_SHARED_SKILLS_DIRmust match — else push a synthetic entry intomissingso verification fails red. (canon < src, so partial packs are caught too.)doctor: extractedlistSkillCanonicalFiles()(shared withbuildSymlinkProbes, DRY) + new exported path-injectedprobeSkillSurface()→ WARN when the install root exists with zero skill canonicals; wired intorunDoctor.npm-pack.test.ts: assert all 9agent-skills/<name>/SKILL.mdare packed; assertcommands/is excluded.install-sentinel.test.ts:Skillsadded to the unconditional-step guard; regression test for the empty-canonical floor.doctor-skill-surface.test.ts: focused unit test forprobeSkillSurface.[Unreleased]→ Fixed.Verification
install-lib.shhunk stashed,verify fails red when source ships skills but zero canonicals existfails (recall_verify_installreturns 0 — silent pass); with the fix restored it passes. Test pins the distinctiveagent skill canonicalsmessage so an unrelated missing symlink can't green it for the wrong reason.bash -n lib/install-lib.shclean ·bun run lintclean.bun test: 1235 pass. The 10 failures are pre-existing and unrelated —recall_configure_opencode_mcp/recall_configure_pi_mcpMCP-config tests (files not touched here); confirmed identical failures on the baseline with this branch's changes stashed.Refs #230, #228. Do not merge — Themis gates.