Files
command-center/agent/managed-skills/fleet-service-precommit-iteration/SKILL.md
T
Frank 135bb2194d agent: repoint roles to frank-medium/dankclaw-3090; sync niri tweaks, memories, managed skills
- 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
2026-09-17 12:27:08 -07:00

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

  1. Edit in the local repo. Run the seams: ./tests/run.sh.
  2. Ship the working files to the host for testing: cat local/file | ssh <host> 'cat > /home/dank/serverAppConfigs/<path>' (then chmod +x if 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").
  3. Test against the live service; iterate until it works.
  4. Before committing, prove the host copy is byte-identical to what you are about to commit: sha256sum locally and on the host. If they differ, you are about to lose work in step 5.
  5. Commit and push.
  6. 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 --short printing nothing.
  7. ./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.sh pulls 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/** and shared/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 .so produced inside a build container) can land in the checkout as root:root; chown them 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.