From 3ef711f1469b8a372f2acae93f72e70e581a8e03 Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 19 Oct 2026 21:48:47 -0700 Subject: [PATCH] fix(deploy): the dragoon gate reads the deployer's own payload-dir twin The containment gate added in #44 parsed scripts/frank-dragoon.env through a $CHECKOUT variable that does not exist in deploy-remote.sh, so the very next deploy died at `set -u` before it touched the unit: ./scripts/deploy-remote.sh: line 1445: CHECKOUT: unbound variable deploy-remote.sh runs from the checkout root and every other path in that block is a parity-twin default (LLM_DRAGOON_CKPT/_VISION/_TOK_DIR), so the payload dir gets the same treatment: LLM_DRAGOON_MODEL_DIR, defaulted to the deployed path, compared directly. The seam now asserts that twin against the env file next to the NPU twins it already checks, and the containment comparison itself is verified both ways (inside accepted; the old outside path and a shared-prefix sibling both refused). --- scripts/deploy-remote.sh | 9 +++++---- tests/frank_dragoon_unit.bats | 3 +++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/deploy-remote.sh b/scripts/deploy-remote.sh index 501f024..de2ed5a 100755 --- a/scripts/deploy-remote.sh +++ b/scripts/deploy-remote.sh @@ -1329,6 +1329,9 @@ deploy_anubis() { # port gate is the same as every cutover since 2026-09-16: nothing # starts until 7770 is released. LLM_DRAGOON_IMAGE="${LLM_DRAGOON_IMAGE:-ghcr.io/peonist-ai/halogen-flash-server@sha256:0c61bf84ac22308a53f5d1ca6b86806702d7039e5ebc51cae4c66621b92fe04a}" +# The payload dir is its own twin because the NPU lane's containment gate below +# reads it; every artifact path under it stays a full literal as usual. +LLM_DRAGOON_MODEL_DIR="${LLM_DRAGOON_MODEL_DIR:-/home/dank/models/halogen-v2-abliterated}" LLM_DRAGOON_CKPT="${LLM_DRAGOON_CKPT:-/home/dank/models/halogen-v2-abliterated/qwen38-flash-next-v2-abliterated.hgn}" LLM_DRAGOON_CKPT_BYTES="${LLM_DRAGOON_CKPT_BYTES:-66687678432}" LLM_DRAGOON_NGRAM="${LLM_DRAGOON_NGRAM:-/home/dank/models/halogen-v2-abliterated/qwen38-flash-next-ngram.hgn}" @@ -1441,10 +1444,8 @@ deploy_llm_dragoon() { # payload dir. A staging dir outside it needs a nested bind whose # mountpoint runc cannot create through a read-only parent, so the # parity twin of the serve gate refuses the shape before the restart. - npu_model_dir="$(sed -nE 's/^FRANK_DRAGOON_MODEL_DIR=(.*)$/\1/p' \ - "$CHECKOUT/scripts/frank-dragoon.env" | tail -1)" - if [[ -n "$npu_model_dir" && "$LLM_DRAGOON_NPU_DIR/" != "$npu_model_dir"/* ]]; then - echo "ERROR: NPU staging dir $LLM_DRAGOON_NPU_DIR is outside the payload dir $npu_model_dir — the lane's files reach the container only through the read-only /models mount" >&2 + if [[ "$LLM_DRAGOON_NPU_DIR/" != "$LLM_DRAGOON_MODEL_DIR"/* ]]; then + echo "ERROR: NPU staging dir $LLM_DRAGOON_NPU_DIR is outside the payload dir $LLM_DRAGOON_MODEL_DIR — the lane's files reach the container only through the read-only /models mount" >&2 return 1 fi if [[ ! -e "$LLM_DRAGOON_DEV_ACCEL" ]]; then diff --git a/tests/frank_dragoon_unit.bats b/tests/frank_dragoon_unit.bats index da1a038..d66555f 100755 --- a/tests/frank_dragoon_unit.bats +++ b/tests/frank_dragoon_unit.bats @@ -357,6 +357,9 @@ $(cat "$TEST_TMP/serve.log")" npu_models="$(sed -nE 's/^HALOGEN_NPU_MODELS=(.*)$/\1/p' "$ENV_FILE")" grep -qF "LLM_DRAGOON_NPU_DIR=\"\${LLM_DRAGOON_NPU_DIR:-$npu_dir}\"" "$DEPLOYER" grep -qF "LLM_DRAGOON_NPU_MODELS=\"\${LLM_DRAGOON_NPU_MODELS:-$npu_models}\"" "$DEPLOYER" + # The deployer's own copy of the payload dir is what the lane's containment + # gate compares against — a stale twin would wave a bad staging path through. + grep -qF "LLM_DRAGOON_MODEL_DIR=\"\${LLM_DRAGOON_MODEL_DIR:-$dir}\"" "$DEPLOYER" net="$(sed -nE 's/^FRANK_DRAGOON_NETWORK=(.*)$/\1/p' "$ENV_FILE")" grep -qF "LLM_DRAGOON_NETWORK=\"\${LLM_DRAGOON_NETWORK:-$net}\"" "$DEPLOYER" } -- 2.54.0