Files
command-center/agent/managed-skills/ssh-fish-host-remote-exec/SKILL.md
T
Frank 689228e60d docs: purge the retired workstation from the knowledge base
Second half of the purge (the first covered the persona, AGENTS.md, README.md,
and the distillation of the per-host pages). Every remaining identifier is
gone: hostname, both LAN addresses, and the Wi-Fi SSID.

34 count-checked substitutions across 22 files — indexes, tool/research pages,
the inventory census, the changelog, one generated HTML report, and five
managed skills. Facts kept, names dropped: a history entry keeps its four-page
listing as a nameless summary, the syslog excerpts keep every timestamp and
line, and the census keeps the .zcompdump rows (the zsh version stamps are the
useful part, the hostname was not).

Deliberately unchanged: install.sh's --host case list and the
packages/<hostname>.pkgs filename, where the hostname is the lookup key.

Left out of scope by Frank's call: agent/memories/** — past-session records the
learn pipeline rewrites.

kb-lint: 0 violations. Residual grep for the hostname, its two IPs, and the
SSID across omp-docs/ and agent/managed-skills/: no hits.
2026-09-28 16:37:38 -07:00

1.8 KiB

name, description
name description
ssh-fish-host-remote-exec Runbook for password-auth SSH exec/file-ship to fleet hosts whose login shell is fish (e.g. blankpad), avoiding the fish-parsing and heredoc-swallow traps

When

Running remote commands or shipping files over SSH to a host whose login shell is fish (blankpad: user blank, reachable only as mDNS FQDN blankpad.local / 192.168.0.83 — bare hostname does not resolve from the workstation).

Procedure

  1. Auth: SSHPASS='<pw>' sshpass -e ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no user@host '...' — password via env, never argv (ps-visible).
  2. Remote exec: ssh host 'cmd' pipes the command string to the login shell (fish). Bashisms like for ... do, $?, heredoc markers fail at parse time on fish (Missing end to balance this for loop). Always wrap compound commands: ssh host 'bash -c "for b in a b c; do command -v $b || echo MISSING; done"' (escape inner $).
  3. File shipping: never combine cat > /remote/path <<EOF with a trailing bash -s in the same ssh command — cat drains stdin, so the interpreter silently runs on empty stdin and prints nothing (silent no-op that looks like success). Ship real bytes via local-file stdin redirect: ssh host 'cat > /remote/path' < localfile, then verify byte-truth with md5sum on both ends.
  4. Exit codes: $? in an unquoted remote command is parsed by fish ($status there) — wrap in bash or drop the status echo; ssh's own exit code propagates to the caller anyway.

Why

Both traps fired during the 2026-09-09 blankpad dotfiles deploy: first probe attempt died on fish loop parsing; a cat > ship silently swallowed the heredoc that was meant for bash -s, deploying the wrong file bytes until md5-compared.