ops(q81): the wrapper forwards __lease-capability to mosaic-old (Mos)

Mos amended ruling (2): with no environment location for
MOSAIC_LEASE_VERSION_PROBE_COMMAND, the wrapper sends only
`__lease-capability` to ~/.npm-global/bin/mosaic-old, so the old CLI's
lease gate still gets its answer. Every other subcommand reaches the
pinned worktree; undo removes the forward with the wrapper. update now
rewrites the wrapper, and status flags a wrapper that differs from what
the script writes. Checked live at 21:17:58Z: the probe answered
{"name":"lease-runtime-activation","version":1}, exit 0.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-11 16:18:21 -05:00
co-authored by Claude Opus 5.5
parent b93211e37e
commit d3ca2c22d6
2 changed files with 30 additions and 7 deletions
+10
View File
@@ -12,3 +12,13 @@
- Alternative inside files Q81 owns: the new wrapper forwards only `__lease-capability`
to ~/.npm-global/bin/mosaic-old. Same effect as the env var (the real old CLI answers),
no env file, removed by undo. Needs Mos's ok, since it differs from the ruling's mechanism.
## Amendment, 2026-10-11T21:17Z (Mos, amending ruling (2))
Mos ruled the env location the original ruling assumed doesn't exist, so the
wrapper forwards instead. `mosaic __lease-capability` goes to
~/.npm-global/bin/mosaic-old; every other subcommand goes to the pinned
worktree. `undo` removes the wrapper and the forward with it. Checked at
21:17:58Z in a login shell: `mosaic __lease-capability` answered
{"name":"lease-runtime-activation","version":1} with exit 0, and `mosaic bus
status` and `mosaic launches list` still answered from the worktree.
+20 -7
View File
@@ -3,7 +3,8 @@
#
# mosaic-cli.sh install [REF] rename the npm-global `mosaic` to `mosaic-old`,
# add a pinned worktree and the wrapper
# mosaic-cli.sh update [REF] move the pinned worktree to REF
# mosaic-cli.sh update [REF] move the pinned worktree to REF and
# rewrite the wrapper
# mosaic-cli.sh undo remove the wrapper and the worktree, rename
# `mosaic-old` back to `mosaic`
# mosaic-cli.sh status what is installed, and whether it drifted
@@ -14,6 +15,9 @@
# checkout, so `mosaic queue` refuses there (the queue runs only in the
# canonical checkout); queue work stays on scripts/mosaic.
#
# The wrapper sends only `__lease-capability` to mosaic-old, so the old
# CLI's lease gate (activation_version_gate.py) still gets its answer.
#
# Writes only: ~/.npm-global/bin/{mosaic,mosaic-old}, the worktree and
# state directory below, and the canonical checkout's worktree list.
set -euo pipefail
@@ -55,16 +59,22 @@ deps() {
echo "node_modules: npm ci done"
}
write_wrapper() {
local tmp
tmp="$(mktemp "$BIN/.mosaic.XXXXXX")"
cat >"$tmp" <<EOF
render_wrapper() {
cat <<EOF
#!/usr/bin/env bash
$MARKER
# Runs the mosaic-stack CLI pinned in $WT.
# The estate CLI it replaced is $BIN/mosaic-old.
# The estate CLI it replaced is $BIN/mosaic-old. Its lease probe still
# answers there, for old-path launches (Mos, Q81, amending ruling (2)).
[ "\${1:-}" = __lease-capability ] && exec "$BIN/mosaic-old" "\$@"
exec "$WT/scripts/mosaic" "\$@"
EOF
}
write_wrapper() {
local tmp
tmp="$(mktemp "$BIN/.mosaic.XXXXXX")"
render_wrapper >"$tmp"
chmod 0755 "$tmp"
mv -f "$tmp" "$BIN/mosaic"
}
@@ -91,6 +101,7 @@ cmd_update() {
[ -z "$(git -C "$WT" status --porcelain --untracked-files=no)" ] || die "$WT has tracked changes; refusing"
git -C "$WT" checkout -q --detach "$sha"
deps
write_wrapper
log "update $sha"
echo "updated: $WT at $sha"
}
@@ -109,7 +120,9 @@ cmd_undo() {
cmd_status() {
local bad=0 sha origin
if is_wrapper; then echo "wrapper: $BIN/mosaic (marker ok)"
if is_wrapper; then
if cmp -s "$BIN/mosaic" <(render_wrapper); then echo "wrapper: $BIN/mosaic (marker ok, matches this script)"
else echo "DRIFT: wrapper differs from what this script writes; run update"; bad=1; fi
elif is_old_link "$BIN/mosaic"; then echo "wrapper: none; $BIN/mosaic is the estate symlink"
[ -e "$WT" ] && { echo "DRIFT: worktree exists but the wrapper is gone (an npm i -g --force?)"; bad=1; }
else echo "DRIFT: $BIN/mosaic is neither the wrapper nor the estate symlink"; bad=1; fi