Files
stack/docs/scratchpads/824-mosaic-skill-cli.md
2026-07-17 17:32:14 -05:00

4.1 KiB

Issue #824 — Mosaic skill CLI and Claude bridge auto-sync

Objective

Deliver mosaic skill register|unregister|list plus install/upgrade reconciliation of every canonical ~/.config/mosaic/skills/* entry into ~/.claude/skills/, without clobbering runtime-owned files or directories.

Scope and constraints

Requirements mapping

  1. Register creates the canonical Claude symlink and is idempotent.
  2. Names are untrusted: reject empty/escaping/absolute/separator/../leading-dash names before filesystem mutation, with clear CLI stderr and nonzero status.
  3. Register repairs only Mosaic-owned dangling symlinks and refuses foreign files, directories, and symlinks.
  4. Unregister removes only symlinks pointing inside the canonical Mosaic skills root and is idempotent when absent.
  5. List reports registered, dangling, foreign, and canonical-but-unregistered skills.
  6. Install and upgrade generically reconcile all canonical skills after framework sync/re-seed, continuing past foreign conflicts without clobbering them.
  7. User/developer documentation describes commands, status meanings, security boundaries, and Claude-only M1 scope.

Plan

  1. Add co-located failing Vitest coverage for all filesystem behaviors and auto-sync.
  2. Run the focused spec and record the expected RED failure.
  3. Commit the red contract as test(#824): ....
  4. Implement the skill bridge and Commander command registration.
  5. Wire reconciliation into wizard finalize and mosaic update re-seed, preserving non-clobber behavior.
  6. Update canonical docs and sitemap if navigation changes.
  7. Run focused tests, package tests, typecheck, lint, and formatting.
  8. Commit implementation/docs as feat(#824): ..., queue-guard, push, open PR with Closes #824., fire completion event, and notify the coordinator.

Progress

  • 2026-07-17: Loaded mission/delivery/TDD/documentation rails, issue #824, active mission state, and relevant installer/update paths.
  • 2026-07-17: Confirmed mosaic update invokes framework/install.sh with MOSAIC_SYNC_ONLY=1; that path exits before existing post-install skill linking, leaving newly present canonical skills unregistered.
  • 2026-07-17: Coordinator addendum classified the user-supplied skill name and runtime symlink target as a path-traversal/symlink-injection surface. Expanded the initial red contract to reject traversal before mutation, preserve every foreign entry, and unregister Mosaic-owned links only.

Tests and evidence

  • RED environment attempt: pnpm --filter @mosaicstack/mosaic exec vitest run src/commands/skill.spec.ts initially could not locate Vitest because this fresh worktree had no dependencies.
  • Dependency setup: pnpm install --frozen-lockfile --store-dir /home/hermes/.local/share/pnpm/store succeeded. The explicit store was required because machine pnpm config incorrectly resolves the default store under /root.
  • RED verified: focused Vitest suite failed with Failed to load url ./skill.js ... Does the file exist?, proving the skill bridge API/implementation is absent before production code.

Risks

  • Symlink replacement must use lstat semantics so dangling links are detectable without following them.
  • Link ownership must be determined lexically/canonically against the canonical skills root without following a foreign destination through an attacker-controlled path.
  • Auto-sync must continue across conflicts while never deleting real files/directories or foreign symlinks.
  • Claude Code discovers filesystem skills at session launch/reload boundaries; bridge creation makes a later /reload-skills or new session able to discover the skill, but cannot mutate an already-cached in-process registry by itself.