Files
serverAppConfigs/tests/frank_large_unit.bats
T
Frank b6ce3afb1f frank-large: CIRU v4.4.1 Orca cutover — root unit, one stream, full context
Operator call 2026-09-19: switch the iGPU endpoint from
halogen-flash-server to jcbtc/Qwen3.8-Flash-CIRU-STRIX-Orca on the CIRU
v4.4.1 runtime with the QSA window hotfix (host build against the private
ROCm 10 SDK), one stream of the full 262144 trained window.  The service
leaves the quadlet shape for a root unit (the same shape as frank-small and
frank-medium: a private-SDK host binary has no image to install and no
generated unit to dodge); the halogen quadlet is archived, the deploy
handler retires it on the host, gates on 7770, and its stray-run sweep
matches the model path so it cannot take frank-small down.
2026-09-19 02:59:01 -07:00

122 lines
5.4 KiB
Bash
Executable File

#!/usr/bin/env bats
# Seam: the frank-large CIRU v4.4.1 root unit on dankclaw.
#
# The 2026-09-19 cutover moved this service out of the halogen-flash-server
# quadlet and onto the CIRU v4.4.1 runtime (QSA window hotfix) serving
# jcbtc/Qwen3.8-Flash-CIRU-STRIX-Orca, as a ROOT unit on a host build -- the
# same shape as frank-small and frank-medium, because a private-SDK host
# binary has no container image to install and no generated unit to dodge.
# This seam pins what a flag list cannot show: the operator's one-stream /
# full-context shape, the payload the launcher refuses to start without, a
# deploy handler that retires the halogen quadlet without deleting it and
# gates on the port, and the fact that the sweep for a stray benchmark run
# cannot take frank-small down with it.
load helpers
ENV_FILE="$REPO_ROOT/scripts/frank-large.env"
UNIT="$REPO_ROOT/scripts/frank-large.service"
SERVE="$REPO_ROOT/scripts/serve-frank-large.sh"
FETCH="$REPO_ROOT/scripts/download-frank-large-orca.sh"
REMOTE_DEPLOY="$REPO_ROOT/scripts/deploy-remote.sh"
@test "the frank-large unit, env and serve files exist where the deployer installs them from" {
[ -f "$ENV_FILE" ]
[ -f "$UNIT" ]
[ -x "$SERVE" ]
}
@test "frank-large is boot-persistent, self-healing and unprivileged" {
grep -q '^WantedBy=multi-user.target$' "$UNIT"
grep -q '^Restart=on-failure$' "$UNIT"
grep -q '^RestartSec=' "$UNIT"
grep -q '^User=dank$' "$UNIT"
# The engine pins staging buffers and the PLE pager's hot window; the
# memlock budget must be unbounded or the load fails on the RLIMIT.
grep -q '^LimitMEMLOCK=infinity$' "$UNIT"
# The unit runs the repo's own serve script with the repo's env.
grep -q 'ExecStart=/home/dank/serverAppConfigs/scripts/serve-frank-large.sh' "$UNIT"
grep -q 'FRANK_LARGE_ENV_FILE=/home/dank/serverAppConfigs/scripts/frank-large.env' "$UNIT"
}
@test "the operator's shape is one stream of the full trained window" {
local ctx slots
ctx="$(sed -nE 's/^CONTEXT_SIZE=([0-9]+)$/\1/p' "$ENV_FILE")"
slots="$(sed -nE 's/^PARALLEL_SLOTS=([0-9]+)$/\1/p' "$ENV_FILE")"
# 262144 is the model's trained window and the GGUF carries no rope
# scaling; the operator asked for full context.
[ "$ctx" -eq 262144 ]
# One slot. This is also the drafter's constraint: the launcher refuses
# MTP with more than one slot, so the two cannot drift apart silently.
[ "$slots" -eq 1 ]
grep -q '^ENABLE_MTP=1$' "$ENV_FILE"
}
@test "frank-large stays text-only until the projector is enabled" {
grep -q '^ENABLE_VISION=0$' "$ENV_FILE"
# The fleet's image path is frank-small; the projector is on disk and is
# one env flip away, but models.yml declares frank-large text-only.
grep -q -- '--mmproj' "$REPO_ROOT/scripts/serve-frank-small.sh"
}
@test "the serve script pins the hotfix runtime and refuses a missing build" {
grep -q 'ciru-runtime-v4.4.1-qsa-hotfix' "$SERVE"
grep -q 'build-gfx1151-sdk/bin/llama-server' "$SERVE"
grep -q 'run-orca-server.sh' "$SERVE"
# A missing runtime or payload is a deploy error with a pointer, not a
# restart loop.
grep -q 'missing built runtime' "$SERVE"
grep -q 'missing target model' "$SERVE"
# The Qwen3.8 template keeps prior thinking blocks across turns only
# when the kwarg is set; the launcher passes --jinja but no kwargs.
grep -q 'preserve_thinking' "$SERVE"
}
@test "the payload is fetched resumably and verified by sha256" {
grep -q 'jcbtc/Qwen3.8-Flash-CIRU-STRIX-Orca' "$FETCH"
grep -q -- '-fL -C -' "$FETCH"
grep -q 'parts.json' "$FETCH"
grep -q 'sha256sum -c SHA256SUMS' "$FETCH"
# The PLE sidecar is the largest transport part; the script must fetch
# and verify it, not just the GGUF.
grep -q 'ple.payload.bin' "$FETCH"
}
@test "the fleet endpoint and alias survive the cutover" {
grep -q '^HOST=0.0.0.0$' "$ENV_FILE"
grep -q '^PORT=7770$' "$ENV_FILE"
grep -q '^MODEL_DIR=/home/dank/models/Qwen3.8-Flash-CIRU-STRIX-Orca$' "$ENV_FILE"
}
@test "the deploy handler retires the halogen quadlet without deleting it" {
grep -q 'retire_halogen_large_quadlet' "$REMOTE_DEPLOY"
grep -q 'HOME/.AGENTTRASH' "$REMOTE_DEPLOY"
! grep -qE '(^|[^[:alnum:]_])rm (-[a-zA-Z]+ )?.*frank-large' "$REMOTE_DEPLOY"
}
@test "the deploy handler installs the root unit, gates the port and refuses a missing payload" {
grep -q 'relink_unit frank-large' "$REMOTE_DEPLOY"
grep -q 'systemctl enable frank-large.service' "$REMOTE_DEPLOY"
grep -q 'wait_port_free 7770' "$REMOTE_DEPLOY"
grep -q '127.0.0.1:7770/health' "$REMOTE_DEPLOY"
grep -q 'LLM_LARGE_MODEL' "$REMOTE_DEPLOY"
grep -q 'LLM_LARGE_PLE' "$REMOTE_DEPLOY"
}
@test "the stray-run sweep cannot take frank-small down" {
# frank-small on this host is ALSO a llama-server. The sweep must match
# the model path, not the binary name, or a frank-large deploy restarts
# the 3090 endpoint.
grep -q "pkill -f 'Qwen3.8-Flash-CIRU-STRIX-Orca'" "$REMOTE_DEPLOY"
# ...and only inside the large handler: extract it and check there is no
# bare binary-name pkill in it.
local large
large="$(sed -n '/^deploy_llm_large() {/,/^}/p' "$REMOTE_DEPLOY")"
! grep -q 'pkill -x llama-server' <<<"$large"
}
@test "the halogen quadlet is archived, not live" {
[ ! -e "$REPO_ROOT/dankclaw/frank-large/quadlet/frank-large.container" ]
[ -f "$REPO_ROOT/dankclaw/.AGENTTRASH/frank-large.container.halogen" ]
}