- config.yml: default/commit -> frank-medium (dankserver); task/tiny/smol/vision -> frank-small (dankclaw-3090); vision xhigh - models.yml: add llamacpp (dankclaw-3090) provider; frank-large preserve_thinking + context notes - niri: focus-ring/border/shadow layout, hot-corners off, re-add noctalia.kdl include; blankpad eDP-1 scale 1.0 - memories: flush rollouts; retire frank_large + marreta_authentik skills; add auth-chain/kv-pool/quadlet-log skills - managed-skills: 40+ new fleet runbook skills - agent/skills: import built-in skill set
3.5 KiB
3.5 KiB
name, description
| name | description |
|---|---|
| fleet-service-precommit-iteration | Iterate on a service that lives in the serverAppConfigs git checkout on a fleet host (dankclaw/dankserver) before committing: ship files for live testing, keep the checkout pullable, then commit and deploy — covers the untracked-files pull trap that recurs every session. |
Iterating on a fleet service before you commit
This repo's contract is git → deploy.sh → host. But live testing needs the new
file on the host before it is committed, and the naive way (copy it into the
host checkout) blocks the very deploy that would install it. This is the loop
that works, plus the traps that cost real time.
The loop
- Edit in the local repo. Run the seams:
./tests/run.sh. - Ship the working files to the host for testing:
cat local/file | ssh <host> 'cat > /home/dank/serverAppConfigs/<path>'(thenchmod +xif it is executed — scp/cat >drops the exec bit, and a container entrypoint mounted from that path fails with status 126, "command found but not executable"). - Test against the live service; iterate until it works.
- Before committing, prove the host copy is byte-identical to what you are
about to commit:
sha256sumlocally and on the host. If they differ, you are about to lose work in step 5. - Commit and push.
- Clean the host checkout so the deploy can pull:
- untracked hand copies → move them out of the checkout
(
mkdir -p /tmp/handcopy && mv <paths> /tmp/handcopy/); - modified tracked files →
git checkout -- <paths>(this discards the hand copy, which is safe only because of step 4); - confirm with
git status --shortprinting nothing.
- untracked hand copies → move them out of the checkout
(
./scripts/deploy.sh <target> --service <svc>— it pushes, pulls ff-only, installs units/config, restarts, waits for health, then runs the Playwright e2e gate.
Traps, in the order they bite
- The pull aborts on hand copies.
deploy.shpulls with ff-only and git refuses: "The following untracked working tree files would be overwritten by merge". Any untracked file in the checkout whose path the pull wants to create stops the deploy — which is exactly the file you just shipped. Always do step 6. git checkout --silently eats uncommitted work. Without step 4 you can destroy the only copy of an edit that exists nowhere else.- A runtime mounts files straight out of the checkout. Here
dankserver/frank-medium/**andshared/grafana/provisioning/**are mounted read-only into containers, so a hand copy takes effect at the next container restart with no deploy. Test that way, then let the deploy make it official. - Root-owned files from a container write (e.g. a patched
.soproduced inside a build container) can land in the checkout asroot:root;chownthem back to the deploy user before git operations. - A restart is not a verification. Health endpoints answer from a stale process, a proxied service can be served by a peer, and a provisioned dashboard may live in unified storage rather than the SQLite table you grep. Verify the specific claim: the new code path's own output, the file's checksum on the host, the API that serves the resource.
Why not keep a scratch copy on the host?
Because the deployed artifact must be the committed one. Iterating outside git
(the /tmp loop is fine for probes) is for measurement scripts; anything the
service actually runs has to land in the checkout, and the checkout has to stay
pullable. Two directories, one rule: probes may live anywhere, runtime state
lives in git.