The adapter is STAGED, NOT SHIPPED: adapter_config.json and
adapter_model.safetensors are in /tank/aimodels/voice-adapters/lv-mccarthy-4b-v1
on fv-ml1, verified byte-identical to gx10's checkpoint-300 at the source, after
the local hop and at the destination. The seat CANNOT load it -- nothing in
--lora-modules references it -- and /v1/models was checked after staging and still
serves exactly the three registered voices plus base.
The adapter carries a README recording the full gate result AND its cost, so it
cannot be read as clean by anyone who finds the directory without the gate record.
A copy is committed at scripts/mccarthy-corpus/gate-results/ADAPTER-README.md for
review. It leads with "STAGED, NOT SHIPPED" and says that if lv-mccarthy is absent
from the seat's model list, the decision has not been made.
The compose edit that would actually register it is prepared in the working tree
and deliberately LEFT UNCOMMITTED. stacks/ is canonical intent that deploy-stack.sh
reads; committing it would assert an intent that is precisely the open question.
Ship-script fix: <run-dir> must be an absolute REMOTE path. A leading ~ is expanded
by the local shell, so ~/r49-runs/... became /home/lkraven/... and gx10 answered
"Permission denied" -- a confusing error for a path problem. It now refuses a
non-absolute path outright, with the reason. Verified: the guard fires on a ~ path
and the real staging succeeded on the absolute one.
Shipping a gated adapter was ad-hoc ssh + rsync three times running. This makes
it one reproducible command for the rest of the line (Faulkner, Morrison,
Chandler are next).
The sha verification is the point, not decoration. "Copied the adapter" is a
claim with no honest form but a read-back, and a truncated or half-written
adapter loads without complaint and serves a subtly different voice. The digest
is taken at the source on gx10, after the local hop, and at the destination on
fv-ml1; any mismatch aborts before the seat is ever told the file exists.
It ships only adapter_config.json and adapter_model.safetensors. A checkpoint
dir also holds optimizer state and RNG, which are large, useless to the seat,
and would make the destination digest disagree with any future re-ship.
It deliberately does NOT edit the compose or restart the seat. Registering an
adapter is a reviewed edit to stacks/voices-seat/compose.yaml, because that file
is where the gate verdict and its caveats get written down for whoever reads it
next -- that is a feature of the current process, not friction to automate away.
Verified against the already-shipped lv-hemingway: the live adapter on fv-ml1 is
byte-identical to gx10's checkpoint-850 on both files, which confirms the file
list and the convention this script encodes.