From d3ca2c22d69b5251bc046e666e0a502debe481bb Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Sun, 11 Oct 2026 16:18:21 -0500 Subject: [PATCH] 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 --- agents/sage/work/q81/lease-gate-notes.md | 10 +++++++++ agents/sage/work/q81/mosaic-cli.sh | 27 ++++++++++++++++++------ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/agents/sage/work/q81/lease-gate-notes.md b/agents/sage/work/q81/lease-gate-notes.md index 82294d87b..67aab98ce 100644 --- a/agents/sage/work/q81/lease-gate-notes.md +++ b/agents/sage/work/q81/lease-gate-notes.md @@ -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. diff --git a/agents/sage/work/q81/mosaic-cli.sh b/agents/sage/work/q81/mosaic-cli.sh index 383620d1e..83dcf0244 100755 --- a/agents/sage/work/q81/mosaic-cli.sh +++ b/agents/sage/work/q81/mosaic-cli.sh @@ -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" <"$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