pod.py config --sync: per-clone live pods.conf copies clobber the shared ~/.ssh/config (RUNNING pod alias dropped twice during #2658 P4)
Highlight text on any card (body, plan, or an event) to anchor a comment, or leave a whole-task comment here. Mention @claude to summon a reply.
No comments yet.
kind: infra
Gap
scripts/pod.py config --sync regenerates the per-user ~/.ssh/config and ~/.claude/mcp.json
from the LIVE pods.conf at <git-common-dir>/eps/pods.conf. That live copy is per repository
clone, while the two config targets are per user. On this VM two clones coexist
(/home/thomasjiralerspong/explore-persona-space/.git/eps/pods.conf, 45 rows, and
/mnt/eps-data/thomasjiralerspong/issue779_task_clone/.git/eps/pods.conf, 23 rows). A pod
provisioned from one clone is registered only in that clone's copy, so any config --sync
run from the other clone rewrites the shared SSH config without it. write_pods_conf's
never-drop-RUNNING guard protects one clone's copy, not the cross-clone write to the shared
targets.
Evidence (task #2658, 2026-09-04)
- pod-2658 (RunPod id 00c34d2rmhne3r, 4x H200, provisioned 05:29Z from the issue779_task_clone
worktree) lost its
Host pod-2658block in~/.ssh/configat 06:35:45Z and again at 07:18:01Z, each time coinciding with a sync from a session in the main clone whose live pods.conf had no pod-2658 row. - The poll monitor watching the P4/P5 production run lost SSH for three consecutive polls the
first time (recovered via
config --syncfrom the owning clone) and fell back to a direct ip:port SSH the second time. - Mitigation applied for the run:
pod.py config --refresh-from-api pod-2658run from the main clone, so both copies now carry the row. This does not fix the class.
Proposed fix (implementer decides the exact shape)
One of, in order of preference:
- Make the live pods.conf per USER, not per clone (e.g.
~/.eps/pods.conf, or a single path resolved independent ofgit-common-dir), with a one-time migration that merges existing per-clone copies. Every clone then reads and writes one file. - Keep per-clone copies but have
config --syncMERGE rows across every live copy it can discover (and/or refresh RUNNING pods of the team from the live RunPod API) before writing the shared targets, so a sync can never drop a RUNNING pod registered elsewhere. - At minimum, make
config --syncrefuse to remove aHostblock for a pod the live RunPod API reports RUNNING, and print the offending clone path.
Add a regression test: two temp "clones" with disjoint pods.conf rows, sync from each, assert the shared SSH config retains both pods.
Acceptance
- A pod provisioned from clone A survives
config --syncfrom clone B in~/.ssh/configand~/.claude/mcp.json. - The regression test above passes.
pod.py config --checkreports the cross-clone state (or the single per-user path) legibly.