---
name: feedback_submodule_autosync_discipline
description: In auto-synced submodules (guru-rmm/guru-connect) don't trust local branch refs — use a worktree or push-by-SHA + verify; assert HEAD==origin/main before audits. Recurring fleet friction.
metadata:
  type: feedback
---

**UPDATE 2026-06-22:** `sync.sh` now protects submodule work on BOTH destructive paths. The
2026-06-21 fix only guarded the Phase-1a init (`sync.sh:391`, init-only-if-unpopulated); the
Phase-3 **post-rebase** reconcile (`sync.sh:525`) still ran `git submodule update --init
--recursive` unconditionally and re-detached/reset everything — that's the path that ate a
feature branch + commits mid-build today. New `submodule_update_safe()` advances ONLY submodules
in the pristine pinned state (clean, detached HEAD) and SKIPS any on a branch or with uncommitted
changes. **So: working on a real branch in a submodule now survives sync.** Prefer that.

Historically (and still as belt-and-suspenders), the auto-sync reset each submodule's working
tree to the **pinned gitlink** (which intentionally lags `main`), and 3-4 Claude sessions can
share one submodule checkout — so local branch refs / HEAD could get reset to the gitlink
mid-work, commits land on a detached HEAD, and `push -u origin <branch>` ships a stale ref.

**Do this instead:**
- **Feature work:** `git worktree add <path> origin/main`, edit + commit + push there, then
  `worktree remove` — OR commit in place, capture `sha=$(git rev-parse HEAD)`, and push by EXPLICIT
  sha: `git push origin <sha>:refs/heads/<branch-or-main>`. Then VERIFY: `git ls-remote origin <ref>`.
  (This session: that push-by-SHA is exactly how the BUG-019 merge + docs landed cleanly.)
- **Before any audit/analysis that reads the working tree:** assert `HEAD == origin/main`
  (`git rev-parse HEAD` vs `git rev-parse origin/main`); if behind, `git fetch` + checkout
  origin/main first, or read `git show origin/main:<file>`. A stale gitlink makes you "fix"
  already-fixed code (a real audit wasted a fix on a bug already closed in main).
- **Never `git checkout -- <shared file>`** to clean up a dirty submodule tree — it clobbers a
  concurrent session's uncommitted work. Move untracked files aside instead.
- HTTPS auth to the gururmm/guru-connect remote (git.azcomputerguru.com) on GURU-5070 uses the
  vaulted `services/gitea` api-token via GIT_ASKPASS (the gitea skill can't inject it — parent repo
  is HTTP, submodule is a different host; SSH key not authorized here).

**Why:** recurring across the fleet (Howard-Home detached-HEAD x2 + a stale-gitlink audit;
GURU-5070 hit a non-fast-forward on a docs push; 2026-06-22 the Phase-3 path reset guru-rmm
mid-build). The 2026-06-21 fix was incomplete (Phase-1a only); the 2026-06-22 fix
(`submodule_update_safe()`) closes the Phase-3 post-rebase path too.

**How to apply:** Work on a real branch in the submodule (now survives sync) and push it to origin.
Belt-and-suspenders for high-stakes writes: push-by-SHA + `ls-remote` verify. Assert
HEAD==origin/main (or read `origin/main:<file>`) before audits; never `checkout --` shared files.

Related: [[gururmm-session-logs-submodule-save]] [[feedback_gururmm_build_verification]]
[[feedback_verify_committed_state_before_push]] [[using-git-worktrees]]
