live: heartbeat sync 2026-10-28T11:37:39-07:00 (Refs #11)

This commit is contained in:
Frank committed 2026-10-28 11:37:39 -07:00
1 parent 38236f35f7
commit a071d71e99
4 files changed
+138 -2

No files matched your search

@@ -0,0 +1,64 @@
---
name: deploy-target-dirty-blob-audit
description: "When scripts/deploy.sh on serverAppConfigs aborts with \"Your local changes to the following files would be overwritten by merge\", prove whether the target's dirty file is already-merged content before restoring it, then deploy from the main checkout."
---
# Deploy target dirty-file audit
`deploy.sh <host>` pushes the local branch, then ssh-pulls on the target. The pull is
`git pull --ff-only origin main` on the TARGET checkout, so any uncommitted edit there
aborts the whole deploy with:
```
error: Your local changes to the following files would be overwritten by merge:
scripts/run-qwen38-bf16.sh
Aborting
```
Nothing is dispatched, so the service is untouched (no wasted outage) — but the deploy
cannot proceed until that path is reconciled. This happens when an agent edited the file
directly on the host (the repo's "never edit on the remote" law) and committed the same
bytes later from a worktree, leaving the host's HEAD behind its own working tree.
## 1. Classify before touching anything
```bash
ssh <host> 'cd <checkout> && git status --porcelain' # every dirty path
ssh <host> 'cd <checkout> && git hash-object <file>
&& git rev-parse <target_sha>:<file>' # compare blobs
```
- Hash equal to the blob the pull wants (`origin/main:<file>`, or a commit main contains)
→ the edit is already merged; restoring is lossless, no trash copy needed.
- Hash matches neither HEAD nor the incoming blob → real unmerged content: `cp` it to
`.AGENTTRASH/YYYYMMDD-topic/` first, then decide.
- `D` entries under `.AGENTTRASH/` (deletions, not modifications) do not block the pull
unless those paths changed between HEAD and main. Leave them — only Frank purges trash.
## 2. Restore, then deploy from the MAIN checkout
```bash
ssh <host> 'cd <checkout> && git checkout -- <file>'
cd ~/Projects/serverAppConfig && ./scripts/deploy.sh <host> --service <svc>
```
`deploy.sh` refuses with `FAIL: deploy.sh must run from the main branch.` when run from a
feature worktree — use the host's `~/Projects/serverAppConfig` main checkout, and pull it
`--ff-only` first so `[1/2] Pushing main to origin` reports `Everything up-to-date`.
A missing server-side path (`/home/dank/models`) plus an `rm -f` in the chain means the
`.rad` was already retired; confirm before relaunching anything that needs it.
## 3. Long deploys never fit an async bash slot
An LLM-service deploy waits up to 20 min for model load plus the Playwright gate, but an
async `bash` call is killed at 600 s. Launch it as a named service instead, then watch the
pid with a deadline-free watcher:
```bash
bash command="cd ~/Projects/serverAppConfig && ./scripts/deploy.sh <host> --service <svc>" \
name=deploy-<host> ready.log="Deployment plan"
# then: while kill -0 <pid> 2>/dev/null; do sleep 20; done (timeout 0, async)
```
`ready.log="Deployment plan"` matches the plan banner, so readiness reports the deploy
started rather than finished; the real result arrives when the watcher completes.