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` - 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), 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. 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`, # mosaic-cli.sh install [REF] rename the npm-global `mosaic` to `mosaic-old`,
# add a pinned worktree and the wrapper # 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-cli.sh undo remove the wrapper and the worktree, rename
# `mosaic-old` back to `mosaic` # `mosaic-old` back to `mosaic`
# mosaic-cli.sh status what is installed, and whether it drifted # 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 # checkout, so `mosaic queue` refuses there (the queue runs only in the
# canonical checkout); queue work stays on scripts/mosaic. # 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 # Writes only: ~/.npm-global/bin/{mosaic,mosaic-old}, the worktree and
# state directory below, and the canonical checkout's worktree list. # state directory below, and the canonical checkout's worktree list.
set -euo pipefail set -euo pipefail
@@ -55,16 +59,22 @@ deps() {
echo "node_modules: npm ci done" echo "node_modules: npm ci done"
} }
write_wrapper() { render_wrapper() {
local tmp cat <<EOF
tmp="$(mktemp "$BIN/.mosaic.XXXXXX")"
cat >"$tmp" <<EOF
#!/usr/bin/env bash #!/usr/bin/env bash
$MARKER $MARKER
# Runs the mosaic-stack CLI pinned in $WT. # 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" "\$@" exec "$WT/scripts/mosaic" "\$@"
EOF EOF
}
write_wrapper() {
local tmp
tmp="$(mktemp "$BIN/.mosaic.XXXXXX")"
render_wrapper >"$tmp"
chmod 0755 "$tmp" chmod 0755 "$tmp"
mv -f "$tmp" "$BIN/mosaic" 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" [ -z "$(git -C "$WT" status --porcelain --untracked-files=no)" ] || die "$WT has tracked changes; refusing"
git -C "$WT" checkout -q --detach "$sha" git -C "$WT" checkout -q --detach "$sha"
deps deps
write_wrapper
log "update $sha" log "update $sha"
echo "updated: $WT at $sha" echo "updated: $WT at $sha"
} }
@@ -109,7 +120,9 @@ cmd_undo() {
cmd_status() { cmd_status() {
local bad=0 sha origin 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" 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; } [ -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 else echo "DRIFT: $BIN/mosaic is neither the wrapper nor the estate symlink"; bad=1; fi