chore(memory): flush runtime memories and promote managed skills
Memory-file flush for the dotfiles-deploy session with the blankpad admin credential scrubbed to a placeholder; sessions transcripts untracked (gitignored) since harness transcripts can carry raw secrets. Managed skills: command-center-dotfiles-import, ssh-fish-host-remote-exec, stash-supersession-audit-before-drop.
This commit is contained in:
1 parent
2db711964b
commit
35b871162c
27 files changed
+180
-67
No files matched your search
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: command-center-dotfiles-import
|
||||
description: "Runbook for deploying the command-center repo (dotfiles env layer + OMP harness) to fleet machines via full-replica rsync and deploy.sh, including override-package mechanics and ssh/sshpass transport gotchas; executed end-to-end on blankpad 2026-09-09."
|
||||
---
|
||||
|
||||
# Command-center fleet deployment (repo = deployment)
|
||||
|
||||
Repo `~/.omp` is itself the deployment: packages are home-relative trees under `dotfiles/<pkg>/`; `scripts/deploy.sh` symlinks live files into the repo checkout. `git pull` + `deploy.sh` is the whole propagation story.
|
||||
|
||||
## Transport decision (agreed with Frank, executed 2026-09-09)
|
||||
- Ship via **full-replica rsync of `/home/dank/.omp/` including `.git`** to `<user>@<host>:/home/<user>/.omp/`, NOT clone-from-Gitea — `main` can be ahead of `origin/main`; push is a user-only trigger, so clone would ship stale state.
|
||||
- Deploy runs on-target as the target user: `bash /home/<user>/.omp/scripts/deploy.sh` (resolves repo via `git -C $(dirname $(realpath $0)) rev-parse --show-toplevel`, so `.git` must be present at target path — full-replica transport guarantees this).
|
||||
|
||||
## Pre-overwrite audit (MANDATORY before first sync on a non-blank host)
|
||||
Diff every file that `deploy.sh --check` reports as DRIFT against the repo copy BEFORE letting quarantine-and-replace run. Host-specific divergence belongs in an override package, not in quarantine:
|
||||
1. Pull divergent live files from target (`ssh ... 'cat <path>' > local-staged-copy`).
|
||||
2. Secret-audit staged copies (grep token/secret/password/key shapes) before anything enters git.
|
||||
3. Compose `dotfiles/zz-<hostname>/` on the source machine from those live copies; commit to repo first.
|
||||
4. Ship package dir via rsync, then run deploy sync — override deploys LAST and wins over base packages.
|
||||
|
||||
## deploy.sh mechanics (verified on blankpad)
|
||||
- `--check` = pure report (ADOPT/LINK/DRIFT lines), writes nothing. Run it first, always.
|
||||
- Default mode = sync: adopt identicals silently, link new, quarantine-and-replace divergents into `.quarantine/<host>/<ts>/` (gitignored; never rm).
|
||||
- **Override-target bug (fixed cc2c652):** `zz-<host>` packages nest base-package dirs internally (`zz-blankpad/niri/.config/...`); target derivation must strip the nested package segment, else overrides deploy to phantom `$HOME/niri/.config/...` while real targets keep pointing at canonical copies (visible symptom: check shows 0 actions but `readlink ~/.zshrc` points at base `zsh/.zshrc`).
|
||||
- systemd units auto-enable only when ExecStart binary resolves on that host; dconf package loads via `dconf load /`, never symlinks.
|
||||
- `core.hooksPath=.githooks` is armed by deploy.sh per machine — set it once post-transfer even before first sync.
|
||||
|
||||
## ssh/sshpass transport gotchas (bit us live)
|
||||
- Resolve target via mDNS FQDN (`avahi-resolve -4 -n <host>.local`); bare hostname may not resolve. Drop-not-refuse on port 22 = sshd down or firewall default-drop, not auth failure — needs local/console fix on target.
|
||||
- `SSHPASS='...' sshpass -e ssh ...` inline per invocation; env passed via tool `env` param did not propagate to the sshpass child process.
|
||||
- Remote login shell may be **fish**: never send bash syntax (`for/do/done`, `$?`) bare through `ssh host 'cmd'`; wrap as `bash /path/script.sh` or `bash -c "..."`.
|
||||
- File shipping: `ssh 'cat > /remote/path' < localfile` (stdin redirect). A here-doc attached to the ssh command is consumed by `cat` — the intended script body becomes the file content, silently. Verify shipped bytes with md5sum compare on both ends; do NOT compare `/dev/stdin` after `cat` drained it (false DIVERGED).
|
||||
|
||||
## Verification of a completed deploy
|
||||
Re-run `deploy.sh --check` → expect exactly zero actions/quarantined/skipped = idempotent steady state. Spot-check `readlink` on override files points into `dotfiles/zz-<host>/`, not base packages.
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
name: ssh-fish-host-remote-exec
|
||||
description: "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 Dankware).
|
||||
|
||||
## 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.
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
name: stash-supersession-audit-before-drop
|
||||
description: "Before dropping a stale git stash, prove it's superseded by HEAD via per-file line-set diff of git show stash@{0}:file vs HEAD; archive as an annotated tag and drop only after auditing unique facts — zero-loss alternative to blind drop."
|
||||
---
|
||||
|
||||
# Stash Supersession Audit Before Drop
|
||||
|
||||
Use when a repo (especially a live-deployment checkout where the working tree IS the deployment, e.g. `~/.omp` command-center) has an old stash whose content may have been superseded by later commits, and dropping blindly risks losing unique facts.
|
||||
|
||||
## Procedure
|
||||
|
||||
1. **Inventory the stash** — see which files it touches:
|
||||
```bash
|
||||
git stash show --stat stash@{0}
|
||||
```
|
||||
2. **Probe for unique content per file.** For each touched file, diff stash version against HEAD and count lines that exist only in the stash version:
|
||||
```bash
|
||||
git show "stash@{0}:<path>" > /tmp/stash_copy
|
||||
# compare normalized line sets; report lines present in stash but absent from HEAD
|
||||
```
|
||||
A file with `unique-vs-HEAD = 0` is fully superseded — safe to drop for that file.
|
||||
3. **Classify each unique-content hit**:
|
||||
- *Stale fact* (superseded by a later refactor, e.g. old model/provider naming) → drop is correct.
|
||||
- *Live durable fact* (e.g. an operational invariant never re-recorded) → extract it into the live memory/docs file or flag to the user before dropping.
|
||||
4. **Archive before dropping** — zero-loss: tag the stash commit, then drop from the stash list:
|
||||
```bash
|
||||
git tag archive/stash-<YYYY-MM-DD>-<base-branch>-wip "stash@{0}"
|
||||
git stash drop "stash@{0}"
|
||||
```
|
||||
The tag pins the full stash object (including its index parent); recoverable later via `git show archive/stash-...` or `git checkout archive/stash-...^3 -- <path>` for the untracked-files third parent if present.
|
||||
|
||||
## Why
|
||||
Stashes are invisible in normal history and expire from reflogs (~90 days). A stash that *looks* superseded can still hold the only copy of a durable fact; tagging converts "drop" into a reversible archive with zero workflow cost.
|
||||
Reference in new issue
Block a user