fix(installer): re-link runtime assets after the CLI stage, so greenfield keeps its enforcement hooks
ci/woodpecker/pr/ci Pipeline was canceled
ci/woodpecker/pr/ci Pipeline was canceled
The framework's install.sh ends by running mosaic-link-runtime-assets, which asks the `mosaic` CLI whether lease enforcement can be activated before deciding whether to wire the #828 hooks into settings.json. Part 1 (framework) runs before Part 2 (npm CLI), so on a first install there is no CLI to ask. The script takes its fail-safe branch, prints a four-line ERROR, and writes settings.json with mutator-gate.py and receipt-observer-client.py stripped out. Measured on canary 1125, rolled back to greenfield, `--next --yes`, no TTY: framework template ~/.config/mosaic/runtime/claude/settings.json mutator-gate.py 1 occurrence receipt-observer-client.py 1 occurrence installed ~/.claude/settings.json after a clean rc=0 install mutator-gate.py wired: False receipt-observer-client.py wired: False So enforcement ends up off because of the order the two halves install in, not because of anything about the host. Falsified by running the same script by hand once the CLI existed: rc=0, both hooks wired: True. The guard's real verdict on that host was 'activatable' the whole time. This adds one more pass after Part 2. The script is idempotent (unchanged files are skipped), so on an upgrade — CLI already present, first pass already correct — it is a no-op. It deliberately does not pass --allow-inactive-enforcement: Part 1 does not either, and a repair pass must not be more permissive than the pass it corrects. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -953,6 +953,39 @@ if [[ "$FLAG_CLI" == "true" ]]; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# Post-install repair: link runtime assets again, now that the CLI exists
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
#
|
||||
# The framework's own install.sh ends by running `mosaic-link-runtime-assets`,
|
||||
# and that script asks the `mosaic` CLI whether lease enforcement can be
|
||||
# activated on this host before deciding whether to wire the #828 enforcement
|
||||
# hooks into settings.json. On a first install there is no CLI to ask — Part 1
|
||||
# runs before Part 2 — so it takes its fail-safe branch, prints a four-line
|
||||
# ERROR, and writes settings.json with the hooks stripped out.
|
||||
#
|
||||
# The result is that a greenfield host always ends up with enforcement
|
||||
# disabled, decided by the order the two halves install in rather than by
|
||||
# anything about the host. Measured on canary 1125, greenfield, both the
|
||||
# `--ref` and `--next` lanes.
|
||||
#
|
||||
# Running it once more here lets the guard reach its real verdict. The script
|
||||
# is idempotent — unchanged files are skipped — so on an upgrade, where the CLI
|
||||
# was already present and the first pass already succeeded, this is a no-op.
|
||||
# No `--allow-inactive-enforcement`: Part 1 does not pass it either, and this
|
||||
# pass must not be more permissive than the one it is correcting.
|
||||
if [[ "$FLAG_CHECK" == "false" && "$FLAG_FRAMEWORK" == "true" && "$FLAG_CLI" == "true" ]]; then
|
||||
RELINK_SCRIPT="$MOSAIC_HOME/tools/_scripts/mosaic-link-runtime-assets"
|
||||
if [[ -x "$RELINK_SCRIPT" && -x "$PREFIX/bin/mosaic" ]]; then
|
||||
step "Runtime assets (re-check with CLI present)"
|
||||
if PATH="$PREFIX/bin:$PATH" "$RELINK_SCRIPT" >/dev/null; then
|
||||
ok "Runtime assets linked"
|
||||
else
|
||||
warn "Runtime asset linking is still degraded — see message above."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# Summary
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
Reference in New Issue
Block a user