--- 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 ` 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 'cd && git status --porcelain' # every dirty path ssh 'cd && git hash-object && git rev-parse :' # compare blobs ``` - Hash equal to the blob the pull wants (`origin/main:`, 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 'cd && git checkout -- ' cd ~/Projects/serverAppConfig && ./scripts/deploy.sh --service ``` `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 --service " \ name=deploy- ready.log="Deployment plan" # then: while kill -0 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.