57 lines
4.1 KiB
Markdown
57 lines
4.1 KiB
Markdown
# 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
|
|
|
|
- Issue: mosaicstack/stack#824
|
|
- Branch: `feat/824-mosaic-skill-cli`
|
|
- M1 runtime: Claude Code only.
|
|
- Pi/Codex parity is documentation-only; no non-Claude bridge implementation.
|
|
- Do not author the downstream `mosaic-context-refresh` skill.
|
|
- Workers do not modify `docs/TASKS.md`, merge, close #824, or touch `main`.
|
|
- TDD is mandatory and red-first; filesystem tests use temporary directories only.
|
|
- Budget: no explicit token cap supplied; use a focused single-worker implementation with no new dependencies.
|
|
|
|
## 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.
|