From b5d4d790314c60f6977f014a4f787e136f931478 Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Fri, 23 Oct 2026 17:40:28 -0500 Subject: [PATCH] docs(row321): set wrapper environment and explain first adoption (#1817) --- agents/gladstone/work/queue-321/BUILD.md | 112 +++++++++++++++++++++++ docs/guides/host-run-sheet.md | 16 ++++ 2 files changed, 128 insertions(+) create mode 100644 agents/gladstone/work/queue-321/BUILD.md diff --git a/agents/gladstone/work/queue-321/BUILD.md b/agents/gladstone/work/queue-321/BUILD.md new file mode 100644 index 000000000..a48c1dc32 --- /dev/null +++ b/agents/gladstone/work/queue-321/BUILD.md @@ -0,0 +1,112 @@ +# Row 321: F7 wrapper environment and F10 first adoption (#1817) + +Owner Gladstone; reviewer Boyd (separate Codex thread); queue/review/landing Sage. +Authorized by sage-3791. Branch gladstone/row321 starts at fetched origin/refactor +833ec1cc8d7c11842efb82e57c1a0b256c8d22d7. The row320 branch is unchanged. +Brief: docs/plans/2026-10-23_host-fixes-1816-brief.md, section +"Brief: F7, the wrapper step's PATH and umask under sudo", including F10; +verified blob 7333f94ba9cfd58f87c5a3580d428b84c65845b6 (requested pin 7333f94ba9cf). +Only the run sheet and this BUILD.md change. No scripts, tests, config, credentials, +queue state, deployment or live host operation changed. No tests or Node commands run. + +## Before and after + +F7: sudo secure_path omits the pinned Node directory, so wrapper creation reaches +instance.sh's bare node and exits127. An inherited umask can leave the bin dir0775. +The MOSAIC_WRAPPER heredoc now sets umask077 and the sheet's existing pinned Node +PATH before mkdir. One sentence names secure_path and why the step sets both. +The existing Mos go remains explicit. No wrapper command is executed here. + +F10: first install omits adoption, so the first activate refuses no-pointer. +The release-transport section now places explicit adoption after both units are +running (section10) and before any activate/upgrade, run as mosaic on Mos's go by +Jason or Mos, citing stack-release.sh:14. It uses the configured dev instance and +external units, with the same pinned Node PATH under sudo. +Adjacent to the upgrade command, the sheet now says only the first upgrade after +adopt takes --no-rehearsal: adopt writes no backup; missing flag refuses no-backup; +later upgrades omit it, because a backup with that flag refuses rehearsal-required. +Source checks: stack-release.sh pointer_for_business refuses no-pointer and directs +adopt; stack-upgrade.sh rehearse handles rc3/no-backup and rc0/rehearsal-required. +This records existing behavior and authority; it adds no requirement or live go. + +## Test-reference grep (negative and positive control) + +The required negative grep covers both F7 and F10 because neither is read by any +matched test. The positive control locates the precheck path that the unit/install +tests actually execute, showing the pathspecs reach their test files. + +Negative grep: + +```sh +git grep -n 'host-run-sheet' -- 'packages/*/tests/*' 'scripts/test-*.sh' +# exit 1 +# no matches +``` + +Positive control: + +```sh +git grep -n 'case2-precheck.sh' -- 'packages/*/tests/*' 'scripts/test-*.sh' +# exit 0 +packages/cli/tests/case1-accept.test.mjs:26:const PRECHECK = `${HOME}/.local/share/mosaic-stack/copies/${COPY}/scripts/case2-precheck.sh`; +packages/cli/tests/case2-install.test.mjs:2:// scripts/case2-precheck.sh's library checks and --library-status mode. Brief: +packages/cli/tests/case2-install.test.mjs:23:const PRECHECK = join(REPO, "scripts", "case2-precheck.sh"); +packages/cli/tests/case2-install.test.mjs:271:// ---- case2-precheck.sh, the library profile (D6a) ---- +packages/cli/tests/case2-install.test.mjs:334:// ---- case2-precheck.sh --library-status (D6b) ---- +packages/cli/tests/case2-unit.test.mjs:2:// and scripts/case2-precheck.sh checks the host before they start. Brief: docs/plans/2026-10-20_case2-rows.md +packages/cli/tests/case2-unit.test.mjs:20:const PRECHECK = join(REPO, "scripts", "case2-precheck.sh"); +packages/cli/tests/case2-unit.test.mjs:588:// ---- case2-precheck.sh ---- +``` + +## Run-sheet diff against the pinned base + +```diff +diff --git a/docs/guides/host-run-sheet.md b/docs/guides/host-run-sheet.md +index d2ba28d7c..96fd4f363 100644 +--- a/docs/guides/host-run-sheet.md ++++ b/docs/guides/host-run-sheet.md +@@ -207,8 +207,21 @@ install -o mosaic -g mosaic -m 0600 /root/.bundle /srv/mosaic/incoming/.bundle /srv/mosaic/src/mosaic-stack + ``` + ++After a first install, once both units are running (section 10), adopt the installed copy before ++any activate or upgrade. This step runs only on Mos's go, with Jason or Mos running it ++(`scripts/stack-release.sh:14`): ++ ++```sh ++sudo -u mosaic -H env PATH=/opt/mosaic-stack/node-/bin:/usr/sbin:/usr/bin:/sbin:/bin \ ++ /srv/mosaic/src/mosaic-stack/scripts/stack-release.sh adopt --instance dev --units external ++``` ++ + Each upgrade, before `stack-upgrade.sh upgrade`: + ++Only the first upgrade after adopt takes `--no-rehearsal`: append it to the upgrade command below. ++Adopt writes no backup, so omitting the flag then refuses `no-backup`. Subsequent upgrades omit it; ++when a backup exists, supplying it refuses `rehearsal-required`. ++ + ```sh + echo " /root/.bundle" | sha256sum -c - + ( +@@ -244,10 +257,13 @@ When a run doesn't exit 0, send Mos the exit and the last lines of `/var/log/mos + After `case2-install.sh` succeeds, create the human CLI wrapper before running + `stack-copy.sh check --units external`. Creating this wrapper is a separate live + step requiring Mos's go (`scripts/stack-copy.sh:3`); the install does not create it. Run only on that go: ++The step runs under sudo's `secure_path`, so it sets its own PATH and umask. + + ```sh + sudo -u mosaic -H /bin/sh <<'MOSAIC_WRAPPER' + cd / || exit 1 ++umask 077 ++PATH=/opt/mosaic-stack/node-/bin:/usr/sbin:/usr/bin:/sbin:/bin; export PATH + mkdir -p -- "$HOME/.npm-global/bin" || exit 1 + "$HOME/src/mosaic-stack/scripts/stack-copy.sh" wrapper --create + MOSAIC_WRAPPER +``` + +## Verification + +No matching test reads the changed lines, so the stop condition did not apply. +No test run or slot is required under sage-3791. Verification is static: the +required grep and positive control above, exact brief/base pins, scoped diff, +and git diff --check. Reviewer Boyd and Sage own review/landing; no approval +or landing is claimed here. diff --git a/docs/guides/host-run-sheet.md b/docs/guides/host-run-sheet.md index d2ba28d7c..96fd4f363 100644 --- a/docs/guides/host-run-sheet.md +++ b/docs/guides/host-run-sheet.md @@ -207,8 +207,21 @@ install -o mosaic -g mosaic -m 0600 /root/.bundle /srv/mosaic/incoming/.bundle /srv/mosaic/src/mosaic-stack ``` +After a first install, once both units are running (section 10), adopt the installed copy before +any activate or upgrade. This step runs only on Mos's go, with Jason or Mos running it +(`scripts/stack-release.sh:14`): + +```sh +sudo -u mosaic -H env PATH=/opt/mosaic-stack/node-/bin:/usr/sbin:/usr/bin:/sbin:/bin \ + /srv/mosaic/src/mosaic-stack/scripts/stack-release.sh adopt --instance dev --units external +``` + Each upgrade, before `stack-upgrade.sh upgrade`: +Only the first upgrade after adopt takes `--no-rehearsal`: append it to the upgrade command below. +Adopt writes no backup, so omitting the flag then refuses `no-backup`. Subsequent upgrades omit it; +when a backup exists, supplying it refuses `rehearsal-required`. + ```sh echo " /root/.bundle" | sha256sum -c - ( @@ -244,10 +257,13 @@ When a run doesn't exit 0, send Mos the exit and the last lines of `/var/log/mos After `case2-install.sh` succeeds, create the human CLI wrapper before running `stack-copy.sh check --units external`. Creating this wrapper is a separate live step requiring Mos's go (`scripts/stack-copy.sh:3`); the install does not create it. Run only on that go: +The step runs under sudo's `secure_path`, so it sets its own PATH and umask. ```sh sudo -u mosaic -H /bin/sh <<'MOSAIC_WRAPPER' cd / || exit 1 +umask 077 +PATH=/opt/mosaic-stack/node-/bin:/usr/sbin:/usr/bin:/sbin:/bin; export PATH mkdir -p -- "$HOME/.npm-global/bin" || exit 1 "$HOME/src/mosaic-stack/scripts/stack-copy.sh" wrapper --create MOSAIC_WRAPPER