docs(row321): wait for loopback health before precheck (#1817, F11)

(cherry picked from commit 9aae73ade2)
This commit is contained in:
jason.woltje committed 2026-10-23 18:15:16 -05:00
1 parent 3fd5307e1e
commit 3569bf54f5
2 files changed
+87 -1

No files matched your search

+70
View File
@@ -99,3 +99,73 @@ Receipt correction: the first commit embedded ordinary diff context lines that
contain a single space. git diff --check flagged those as trailing whitespace.
This follow-up uses the exact zero-context diff instead. The run sheet is
unchanged, no tests or Node commands run, and no amend or force-push is used.
## F11 addition (sage-3805, mos-1549, ops-0275)
The brief was extended after F7/F10 drafting and re-pinned at revision3733:
canonical local commit a9bae9af2, same F7 section anchor, full verified blob
0e684ef2103447dcc2013b6bf81b1c4ca5bbc0bd (requested pin0e684ef21034).
Read using git show from the canonical checkout; no fetch, rebase or queue write
is required. This new pin supersedes the earlier brief pin for this follow-up.
Defect: a precheck one second after unit start found no bus.sqlite yet.
Section10 now requires loopback healthz success after a unit start before any
case2-precheck.sh, including section9's --library-status. It uses the same
127.0.0.1:<port>/healthz curl form as scripts/case1-accept.sh:458. The subshell
tries at most30 times, each curl capped at2 seconds, with1 second between failed
attempts (at most89 seconds plus scheduling overhead). Exhaustion prints STOP
and exits only the subshell. The instruction says to stop before precheck/adopt;
it does not exit the interactive operator shell. The section9 library-gitea row
now explicitly requires this bounded wait before --library-status. <port> is the
installed Console unit's --port, not an assumed port or business name.
No host action, test, Node command or credential access occurred.
Required grep repeated for the widened scope:
```sh
git grep -n 'host-run-sheet' -- 'packages/*/tests/*' 'scripts/test-*.sh'
# exit1, no matches
git grep -n 'case2-precheck.sh' -- 'packages/*/tests/*' 'scripts/test-*.sh'
# exit0, positive control; output follows
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 ----
```
No test reads the changed run-sheet lines; the stop condition does not apply.
No test run is needed under the docs-only brief. Static verification checks both
locations, retry limit/timeout, the loopback URL, unchanged F7/F10 and scoped diff.
F11 delta against d9400f0d3 (git diff --unified=0):
```diff
diff --git a/docs/guides/host-run-sheet.md b/docs/guides/host-run-sheet.md
index 96fd4f363..e9fa87f24 100644
--- a/docs/guides/host-run-sheet.md
+++ b/docs/guides/host-run-sheet.md
@@ -322 +322 @@ file with `stat -c '%U %a %n' PATH`, never `cat`. `<business>` is the host's bus
-| `/srv/mosaic/.config/mosaic-dev/secrets/<business>/` | `library-gitea` | 0600 | mosaic | library | `case2-precheck.sh --business <business> --library-status`, after the bus is up: `library-last-error library-credential-missing` until it's placed, then `library <project> last fetched ...` |
+| `/srv/mosaic/.config/mosaic-dev/secrets/<business>/` | `library-gitea` | 0600 | mosaic | library | After a unit start, wait for loopback `/healthz` with the bounded retry in section 10 before `case2-precheck.sh --business <business> --library-status`: `library-last-error library-credential-missing` until it's placed, then `library <project> last fetched ...` |
@@ -357,0 +358,16 @@ None by hand. I2's `case2-unit.sh` enables both units, starts the bus, then the
+After a unit start, wait for the Console's loopback `/healthz` to succeed before running
+`case2-precheck.sh`, including `--library-status` in section 9. Replace `<port>` with the installed
+Console unit's `--port`. This retry is bounded to 30 attempts, each with a 2-second timeout, with
+1 second between failed attempts. If it prints STOP, stop here; do not run the precheck or adopt.
+
+```sh
+(
+ attempts=0
+ until curl -fsS --max-time 2 -o /dev/null 'http://127.0.0.1:<port>/healthz'; do
+ attempts=$((attempts + 1))
+ [ "$attempts" -lt 30 ] || { echo "STOP: loopback healthz did not become ready; do not continue" >&2; exit 1; }
+ sleep 1
+ done
+)
+```
+
```
+17 -1
View File
@@ -319,7 +319,7 @@ file with `stat -c '%U %a %n' PATH`, never `cat`. `<business>` is the host's bus
|---|---|---|---|---|---|
| `/srv/mosaic/.config/mosaic-dev/secrets/` | `claude-session.env`, one line `ZAI_API_KEY=...` | 0600 | mosaic | library | `<path> sets ZAI_API_KEY` |
| `/srv/mosaic/.config/mosaic-dev/secrets/` | the Console's proof file, the path the args file's `--proof-file` names | 0600 or 0400 | mosaic | library | none. `case2-unit.sh` refuses at render. Precheck line missing. |
| `/srv/mosaic/.config/mosaic-dev/secrets/<business>/` | `library-gitea` | 0600 | mosaic | library | `case2-precheck.sh --business <business> --library-status`, after the bus is up: `library-last-error library-credential-missing` until it's placed, then `library <project> last fetched ...` |
| `/srv/mosaic/.config/mosaic-dev/secrets/<business>/` | `library-gitea` | 0600 | mosaic | library | After a unit start, wait for loopback `/healthz` with the bounded retry in section 10 before `case2-precheck.sh --business <business> --library-status`: `library-last-error library-credential-missing` until it's placed, then `library <project> last fetched ...` |
| `/srv/mosaic/.config/mosaic-dev/secrets/agents/<business>/<agent>/` | one file per service | 0600, dirs 0700 | mosaic | both | none. Filled only by `mosaic credentials issue`, or Approve after #436. Never by hand. |
The installer key, `<configDir>/secrets/hosts/<business>/<hostId>/installer`, is not a slot anyone places.
@@ -355,4 +355,20 @@ Precheck line: `ok notifier config <dataRoot>/notify/<business>/notify.json
None by hand. I2's `case2-unit.sh` enables both units, starts the bus, then the Console (Q189, mos-1122).
`stack-upgrade.sh` stops and starts both units itself.
After a unit start, wait for the Console's loopback `/healthz` to succeed before running
`case2-precheck.sh`, including `--library-status` in section 9. Replace `<port>` with the installed
Console unit's `--port`. This retry is bounded to 30 attempts, each with a 2-second timeout, with
1 second between failed attempts. If it prints STOP, stop here; do not run the precheck or adopt.
```sh
(
attempts=0
until curl -fsS --max-time 2 -o /dev/null 'http://127.0.0.1:<port>/healthz'; do
attempts=$((attempts + 1))
[ "$attempts" -lt 30 ] || { echo "STOP: loopback healthz did not become ready; do not continue" >&2; exit 1; }
sleep 1
done
)
```
Precheck line: none. Both units active after the render: precheck line missing.