promote: /mosaic-promote slash command shipped in runtime/claude/commands/ but not seeded into the seat's CLAUDE_CONFIG_DIR/commands/ → 'Unknown command', UserPromptSubmit hook never fires (fomo-lin E2E, #1124 fix re-run) #1125

Open
opened 2026-08-08 22:00:42 +00:00 by scooby · 1 comment
Collaborator

With #1124 fix (b) in place, mosaic promote now RESOLVES the seat correctly (BFS walk finds the claude child's MOSAIC_LEASE_SESSION_ID — confirmed working). The next link then failed: the injected /mosaic-promote returned ● Unknown command: /mosaic-promote in the seat, so the UserPromptSubmit ^/mosaic-promote$ hook (promote-begin) never fired → PROMOTION_TIMEOUT.

Root cause: the slash command IS shipped at ~/.config/mosaic/runtime/claude/commands/mosaic-promote.md, but the seat's home (CLAUDE_CONFIG_DIR=~/.config/mosaic/.claude) had no commands/ dir — the framework's settings-seeding step wires settings.json into the seat home but NOT the companion commands/ dir. Claude Code loads slash commands from $CLAUDE_CONFIG_DIR/commands/, so an unseeded seat rejects the trigger. Same asset-seeding gap class as F7/#1116 (MCP block dropped).

Worked around on fomo-lin by copying the command file into the seat's commands/ and relaunching — after which /mosaic-promote is recognized and the hook fires (see #1126 for what happens next).

Fix: seat-home composition (W-F1 / the gated-seat seeding path) must install commands/mosaic-promote.md alongside the gated settings.json. Ties into HARNESS-HOMES gap 7 (base must own all companion assets, not just settings). Filed by scooby (fomo-lin).

With #1124 fix (b) in place, `mosaic promote` now RESOLVES the seat correctly (BFS walk finds the claude child's MOSAIC_LEASE_SESSION_ID — confirmed working). The next link then failed: the injected `/mosaic-promote` returned `● Unknown command: /mosaic-promote` in the seat, so the `UserPromptSubmit ^/mosaic-promote$` hook (promote-begin) never fired → PROMOTION_TIMEOUT. **Root cause:** the slash command IS shipped at `~/.config/mosaic/runtime/claude/commands/mosaic-promote.md`, but the seat's home (`CLAUDE_CONFIG_DIR=~/.config/mosaic/.claude`) had no `commands/` dir — the framework's settings-seeding step wires settings.json into the seat home but NOT the companion `commands/` dir. Claude Code loads slash commands from `$CLAUDE_CONFIG_DIR/commands/`, so an unseeded seat rejects the trigger. Same asset-seeding gap class as F7/#1116 (MCP block dropped). **Worked around** on fomo-lin by copying the command file into the seat's `commands/` and relaunching — after which `/mosaic-promote` is recognized and the hook fires (see #1126 for what happens next). **Fix:** seat-home composition (W-F1 / the gated-seat seeding path) must install `commands/mosaic-promote.md` alongside the gated settings.json. Ties into HARNESS-HOMES gap 7 (base must own all companion assets, not just settings). Filed by scooby (fomo-lin).

Installer-seed verification complete (scooby, 2026-08-09, at #1109 head 1a871524):

  • Static: mosaic-link-runtime-assets lines 236-240 unconditionally copy every file in $MOSAIC_HOME/runtime/claude/commands/ to ~/.claude/commands/ via copy_file_managed; runs independent of the settings-guard (guard helpers return 0 when degraded). Source runtime/claude/commands/mosaic-promote.md is tracked at head (blob b80c0924).
  • Empirical clean-host reproduction: temp MOSAIC_HOME populated strictly from the #1109-head tree, fresh scratch HOME with no .claude/commands/ → after running the verbatim seeding block, mosaic-promote.md present and git hash-object = b80c0924, byte-identical to source.
  • The shipped command content is the mechanical framing ("Mosaic lease promotion was processed mechanically; no action is needed") — the echo-era wording that caused seat-model refusal loops in earlier testing was a stale pre-install artifact, not branch content.

Recommend closing this when #1109 merges.

Installer-seed verification complete (scooby, 2026-08-09, at #1109 head `1a871524`): - **Static**: `mosaic-link-runtime-assets` lines 236-240 unconditionally copy every file in `$MOSAIC_HOME/runtime/claude/commands/` to `~/.claude/commands/` via `copy_file_managed`; runs independent of the settings-guard (guard helpers return 0 when degraded). Source `runtime/claude/commands/mosaic-promote.md` is tracked at head (blob `b80c0924`). - **Empirical clean-host reproduction**: temp MOSAIC_HOME populated strictly from the #1109-head tree, fresh scratch HOME with no `.claude/commands/` → after running the verbatim seeding block, `mosaic-promote.md` present and `git hash-object` = `b80c0924`, byte-identical to source. - The shipped command content is the mechanical framing ("Mosaic lease promotion was processed mechanically; no action is needed") — the echo-era wording that caused seat-model refusal loops in earlier testing was a stale pre-install artifact, not branch content. Recommend closing this when #1109 merges.
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#1125