Skip to content

fix(hpc/sync): create remote project dir before parallel push rsyncs - #112

Merged
Jammy2211 merged 1 commit into
mainfrom
claude/hpc-sync-first-push-race-r2wj7d
Aug 17, 2026
Merged

fix(hpc/sync): create remote project dir before parallel push rsyncs#112
Jammy2211 merged 1 commit into
mainfrom
claude/hpc-sync-first-push-race-r2wj7d

Conversation

@Jammy2211

@Jammy2211 Jammy2211 commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

The bug

On the first push to a new remote project, push() launched the CODE_DIRS rsyncs in parallel before anything had created ${HPC_BASE}/${PROJECT_NAME}. rsync only creates the final path level, so every one of them died with mkdir failed: No such file or directory.

The later [root files] rsync then created the base dir as a side effect, so dataset/ synced fine and the whole command exited 0. The failure stayed silent until sbatch could not find hpc/batch_gpu.

Found during the slope_hierarchy first push (job 330464 postmortem, 2026-07-16).

Reproduced against the unmodified script with a local fake-HPC harness (real rsync, stubbed ssh):

push exit code: 0
REMOTE/slope_hierarchy/activate.sh
REMOTE/slope_hierarchy/dataset/d1/data.fits      <- dataset landed
did hpc/batch_gpu arrive?  NO  <-- sbatch would fail

The fix

Both changes are confined to push().

  1. Root causessh mkdir -p the remote project dir before the parallel rsyncs, matching what pull, pull_logs and push_data_init already do. Skipped under --dry-run so status stays side-effect free.
  2. Why it went unnoticed — plain wait returns its own status, so a failed backgrounded rsync was swallowed even under set -euo pipefail. The background PIDs are now collected and waited on individually; push() names the failing directory and returns 1, so push-submit aborts instead of submitting against an incomplete tree.

The second change is included because the reported damage was that the failure was silent until sbatch — the mkdir alone fixes this instance, but any future first-push failure would still have been invisible.

Verification

Case Before After
First push to fresh remote exit 0, hpc/batch_gpu missing exit 0, full tree transferred
Injected transfer failure exit 0, silent exit 1, names the dir
push-submit with a failure reached sbatch aborts before sbatch
Re-push / --no-data exit 0 exit 0
status (dry-run) exit 1, no ssh exit 1, no ssh — 0 ssh calls, nothing created

status exiting 1 is pre-existing on both fresh and existing remotes; the baseline was checked and is unchanged by this diff.

Sibling repos

The same push() exists in autofit_assistant (byte-identical file) and autogalaxy_assistant (differs only in CODE_DIRS). Both carry the same defect and have matching PRs. autocti_assistant has no hpc/sync and is unaffected.

Note on the boundary check

The first boundary run on this PR failed for a reason pre-existing on main and unrelated to this diff (CHOOSING_YOUR_AI_TOOL.md unclassified — see the comment below). That is now fixed and merged as PyAutoLabs/PyAutoBrain#228, so the check passes against main directly; the temporary Brain-ref: declaration this PR carried while that was in flight has been removed.

On the first push to a new remote project, push() launched the CODE_DIRS
rsyncs in parallel before anything had created ${HPC_BASE}/${PROJECT_NAME}.
rsync only creates the final path level, so all of them died with
"mkdir failed: No such file or directory". The later [root files] rsync
then created the base dir, so dataset/ synced and push exited 0 — the
failure stayed silent until sbatch could not find hpc/batch_gpu
(slope_hierarchy first push, job 330464 postmortem, 2026-07-16).

Two changes:

- ssh mkdir -p the remote project dir before the parallel rsyncs, matching
  what pull/pull_logs/push_data_init already do. Skipped under --dry-run so
  `status` stays side-effect free.
- Collect the background PIDs and wait on each one. Plain `wait` returns its
  own status, so a failed backgrounded rsync was swallowed even under
  `set -e`. push() now names the failing directory and returns 1, so
  push-submit aborts instead of submitting against an incomplete tree.

Verified against a local fake-HPC harness (real rsync, stubbed ssh):
first push previously exited 0 without hpc/batch_gpu and now transfers the
full tree; an injected transfer failure now exits 1 and stops push-submit
before sbatch; re-push, --no-data and status are unchanged.

Copy link
Copy Markdown
Collaborator Author

CI status: boundary is red on the base branch, not from this diff

wiki-currency ✅. boundary ❌, but the failure predates this branch and is unrelated to it:

check_boundary: 1 file(s) in autolens_assistant fall on neither side of the template boundary:
  ✗ CHOOSING_YOUR_AI_TOOL.md

This diff touches exactly one file, hpc/sync. CHOOSING_YOUR_AI_TOOL.md arrived on main in 64018f8 ("Release 2026.8.17.1"), which is this branch's base commit — so any PR opened against main right now fails the same check. The sibling PRs confirm it: the same boundary job passes on autogalaxy_assistant#15, whose profile is complete, and the file exists only in this repo.

What it needs

The checker requires the file classified in both places, agreeing:

  1. modes/maintainer.md, ## Assistant-as-template — it is mentioned at lines 101 and 128, but not listed under a boundary marker.
  2. PyAutoBrain agents/conductors/clone/_clone.py, REFERENCE_PROFILES['autolens_assistant'] — not listed at all.

The natural classification looks like mixed (generic structure, domain-specific values): the platform mechanics clone verbatim, while the PyAutoLens naming, the lens-modelling examples and the issues URL are domain. That mirrors FREE_TIER_SETUP.md, already in _SHARED_MIXED for the same reason. Since the file exists only in this repo, it belongs in this profile's own mixed rather than the shared list.

That is a template-boundary decision spanning two repos and unrelated to this bug fix, so I have not folded it into this PR. Happy to open a separate one if that classification is right.


Generated by Claude Code

@Jammy2211 Jammy2211 closed this Aug 17, 2026
@Jammy2211 Jammy2211 reopened this Aug 17, 2026
@Jammy2211
Jammy2211 merged commit 4b4d8a7 into main Aug 17, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants