feat(launch): force-load fleet-critical Pi skills + reconcile skill docs #555

Merged
jason.woltje merged 1 commits from feat/pi-mosaic-tools-skill into main 2026-06-19 18:31:03 +00:00
Owner

Problem

mosaic [yolo] pi launched Pi with ['--no-skills'] whenever MOSAIC_PI_SKILL_MODE
was unset — which is the default on every shell, systemd unit, and launcher. Result:
Pi loaded zero Mosaic skills, so fleet workers never saw the ~/.config/mosaic/tools/
wrappers and routinely improvised raw tmux send-keys / tea / gh. (Pi's own
RUNTIME.md claimed skills "load natively" — direct contradiction of the launcher default.)

Root-cause investigation (Step-1 verdict): TOOLS.md is injected into Pi's prompt
(PR #554 already raised its salience); the remaining gap is that skills never load.

Fix

buildPiSkillArgs() now force-loads a small fleet-critical skill set on every Pi
launch, regardless of mode. An explicit --skill <dir> overrides --no-skills for that
path, so we surface the must-use toolkit without the ~100-skill context bloat of
MOSAIC_PI_SKILL_MODE=all.

  • DEFAULT_PI_FORCE_SKILLS = ['mosaic-tools']; forcedPiSkillArgs() maps each to
    --skill <MOSAIC_HOME>/skills/<name>, existsSync-guarded → a complete no-op until the
    skill is synced (safe to merge before the skill lands).
  • Merged into all three return paths (none / all / discover); all dedups via
    mergeSkillArgs() so a discovered skill isn't double-loaded.
  • Override with MOSAIC_PI_FORCE_SKILLS (colon-separated; empty string disables).
  • claude / codex / opencode paths untouched.

Also in this PR

  • runtime/pi/RUNTIME.md — reconcile the "skills load natively" drift with the real
    default-off + force-load + MOSAIC_PI_SKILL_MODE behavior.
  • templates/agent/** — fix stale ~/.config/mosaic/rails/tools/ (60 occurrences
    across 12 scaffold templates; rails/ no longer exists). Mechanical, toolkit-path-only;
    quality-rails repo refs untouched.

Companion PR (required for runtime effect)

The mosaic-tools skill ships in mosaicstack/agent-skills#1. This launcher PR is inert
(existsSync no-op) until that skill is synced.

Verification

  • pnpm typecheck (turbo, 41/41) · pnpm lint · pnpm test 302 passed (33 files)
  • prettier --check on CI-matched files (.md.template files aren't in CI's glob)
  • New deterministic unit coverage for buildPiSkillArgs (none/all/discover/no-disk/dedup)
    and piForceSkillNames (unset vs empty-string-disable vs colon-list parsing).
  • Independent code review performed (APPROVE-WITH-NITS); both raised points remediated
    (guarantee forced skills under all + dedup; empty-string-disable test).

Follow-up (NOT auto-applied)

Live fleet sessions need mosaic-sync-skills (to pull mosaic-tools) and a launcher
upgrade to pick this up. Do not auto-reseed running sessions — coordinate via Mos.

🤖 Generated with Claude Code

## Problem `mosaic [yolo] pi` launched Pi with `['--no-skills']` whenever `MOSAIC_PI_SKILL_MODE` was unset — which is the default on every shell, systemd unit, and launcher. Result: **Pi loaded zero Mosaic skills**, so fleet workers never saw the `~/.config/mosaic/tools/` wrappers and routinely improvised raw `tmux send-keys` / `tea` / `gh`. (Pi's own RUNTIME.md claimed skills "load natively" — direct contradiction of the launcher default.) Root-cause investigation (Step-1 verdict): TOOLS.md **is** injected into Pi's prompt (PR #554 already raised its salience); the *remaining* gap is that skills never load. ## Fix `buildPiSkillArgs()` now force-loads a small **fleet-critical** skill set on every Pi launch, regardless of mode. An explicit `--skill <dir>` overrides `--no-skills` for that path, so we surface the must-use toolkit **without** the ~100-skill context bloat of `MOSAIC_PI_SKILL_MODE=all`. - `DEFAULT_PI_FORCE_SKILLS = ['mosaic-tools']`; `forcedPiSkillArgs()` maps each to `--skill <MOSAIC_HOME>/skills/<name>`, **existsSync-guarded** → a complete no-op until the skill is synced (safe to merge before the skill lands). - Merged into all three return paths (`none` / `all` / `discover`); `all` dedups via `mergeSkillArgs()` so a discovered skill isn't double-loaded. - Override with `MOSAIC_PI_FORCE_SKILLS` (colon-separated; empty string disables). - `claude` / `codex` / `opencode` paths untouched. ### Also in this PR - **`runtime/pi/RUNTIME.md`** — reconcile the "skills load natively" drift with the real default-off + force-load + `MOSAIC_PI_SKILL_MODE` behavior. - **`templates/agent/**`** — fix stale `~/.config/mosaic/rails/` → `tools/` (60 occurrences across 12 scaffold templates; `rails/` no longer exists). Mechanical, toolkit-path-only; `quality-rails` repo refs untouched. ## Companion PR (required for runtime effect) The `mosaic-tools` skill ships in **mosaicstack/agent-skills#1**. This launcher PR is inert (existsSync no-op) until that skill is synced. ## Verification - `pnpm typecheck` (turbo, 41/41) ✅ · `pnpm lint` ✅ · `pnpm test` 302 passed (33 files) ✅ - `prettier --check` on CI-matched files ✅ (`.md.template` files aren't in CI's glob) - New deterministic unit coverage for `buildPiSkillArgs` (none/all/discover/no-disk/dedup) and `piForceSkillNames` (unset vs empty-string-disable vs colon-list parsing). - Independent code review performed (APPROVE-WITH-NITS); both raised points remediated (guarantee forced skills under `all` + dedup; empty-string-disable test). ## Follow-up (NOT auto-applied) Live fleet sessions need `mosaic-sync-skills` (to pull `mosaic-tools`) **and** a launcher upgrade to pick this up. Do **not** auto-reseed running sessions — coordinate via Mos. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
jason.woltje added 1 commit 2026-06-19 18:21:55 +00:00
feat(launch): force-load fleet-critical Pi skills + reconcile skill docs
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
5c083763c8
Pi workers launched via `mosaic [yolo] pi` never loaded any skill because
buildPiSkillArgs emitted `--no-skills` whenever MOSAIC_PI_SKILL_MODE was
unset (the default everywhere), so maintained `~/.config/mosaic/tools/`
wrappers stayed invisible and workers improvised raw `tmux send-keys` /
`tea` / `gh`. An explicit `--skill` overrides `--no-skills` for that path,
so we now force-load a small fleet-critical set (default: `mosaic-tools`)
on every Pi launch regardless of mode — no full-catalog context bloat.

- launch.ts: add DEFAULT_PI_FORCE_SKILLS + forcedPiSkillArgs(); merge into
  every buildPiSkillArgs() return path (existsSync-guarded → no-op until the
  skill is synced). Override via MOSAIC_PI_FORCE_SKILLS (colon-separated;
  empty string disables).
- launch.spec.ts: deterministic 4th-param injection + force-load coverage.
- runtime/pi/RUNTIME.md: reconcile the "skills load natively" drift with the
  real default-off + force-load + MOSAIC_PI_SKILL_MODE behavior.
- templates/agent/**: fix stale `~/.config/mosaic/rails/` → `tools/` (60
  occurrences across 12 scaffold templates; `rails/` no longer exists).

Companion skill `mosaic-tools` ships in mosaic/agent-skills.
Follow-up (NOT auto-applied): live fleet needs `mosaic-sync-skills` +
launcher upgrade to pick up the new skill on running sessions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QoYiBeKNh3BiYtAJS5Z587
jason.woltje merged commit 8c45857859 into main 2026-06-19 18:31:03 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#555