From 6ba19f6f4819297450427ffb2df990c59addf7a1 Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 5 Oct 2026 19:27:21 -0700 Subject: [PATCH] frank-primary: deploy health gate reads the body (FreeToken 200-loading) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FreeToken's /health returns 200 with {"status":"loading"} while the engine loads — the FastAPI front end binds before the scheduler is up. Measured 2026-10-06: the deploy gate went green after 6s while 131 shards were still paging in (vLLM 503'd during load, which made the bare curl honest there). The frank-primary gate now loops until status:ok; the MainPID stray-port guard is unchanged. --- scripts/deploy-remote.sh | 21 ++++++++++++++++++++- tests/frank_primary_unit.bats | 8 +++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/scripts/deploy-remote.sh b/scripts/deploy-remote.sh index 8f7ad46..662fa18 100755 --- a/scripts/deploy-remote.sh +++ b/scripts/deploy-remote.sh @@ -1339,7 +1339,26 @@ deploy_llm_primary() { run_privileged systemctl restart frank-primary.service # Cold start: FP8 page-in plus torch compile/graph capture (~15 min cold, # measured 2026-09-29). Parity with every predecessor on this port. - wait_for_health frank-primary http://127.0.0.1:7770/health 1800 || return 1 + # FreeToken's /health returns 200 with {"status":"loading"} while the + # engine loads (the FastAPI front end binds before the scheduler is + # up), so a bare 200 false-greens — measured 2026-10-06: "healthy after + # 6 s" while 131 shards were still paging in. vLLM 503'd during load, + # which made the bare curl honest there; FreeToken needs the BODY read. + # Only status:"ok" counts. (The MainPID check below still guards the + # stray-port case.) + local i ok=0 + for ((i=1; i<=900; i++)); do + if curl -fsS http://127.0.0.1:7770/health 2>/dev/null | grep -q '"status":"ok"'; then + echo "frank-primary engine healthy after approximately $((i * 2))s" + ok=1 + break + fi + sleep 2 + done + if [[ "$ok" != 1 ]]; then + echo "FAIL: frank-primary never reached /health status ok in 1800s" >&2 + return 1 + fi # False-green hardening (the 2026-09-26 lesson): a bare curl against the # port cannot tell WHO answers — a stray probe holding :7770 satisfies # it while the unit is stopped. The deploy is only green if the unit diff --git a/tests/frank_primary_unit.bats b/tests/frank_primary_unit.bats index 3a77496..ed7bc58 100755 --- a/tests/frank_primary_unit.bats +++ b/tests/frank_primary_unit.bats @@ -239,7 +239,13 @@ DOCKERFILE="$REPO_ROOT/scripts/docker/frank-primary-freetoken.Dockerfile" grep -q 'relink_unit frank-primary' "$REMOTE_DEPLOY" grep -q 'systemctl enable frank-primary.service' "$REMOTE_DEPLOY" grep -q 'systemctl restart frank-primary.service' "$REMOTE_DEPLOY" - grep -q 'wait_for_health frank-primary http://127.0.0.1:7770/health 1800' "$REMOTE_DEPLOY" + # The health gate reads the BODY, not just the HTTP code: FreeToken + # returns 200 with {"status":"loading"} while the engine loads (the + # FastAPI front end binds before the scheduler is up — a bare 200 + # false-greened a deploy at 6 s while 131 shards were still paging in, + # measured 2026-10-06). Only status:"ok" counts. + grep -q 'curl -fsS http://127.0.0.1:7770/health' "$REMOTE_DEPLOY" + grep -q 'never reached /health status ok' "$REMOTE_DEPLOY" } @test "the deployer will not report green on a stray port-holder" {