feat(deploy): automatic hardlink repair built into deployment pipeline

User insight: hardlink breakage only happens at deploy time (scp file
replacement / git checkout-merge), so detection must be welded INTO the
deploy pipeline, not left to daily audit.

Three automatic layers, no reliance on discipline:
1. systemd path watcher (profile-scripts-sync.path): watches
   deploy/profile-scripts/ directory, auto-fires sync_profile_scripts.sh
   on any change. Verified: fires within 4s of file replacement, logs to
   gateway/logs/link_sync.log (runs as hmo user)
2. git hooks (.git/hooks/post-merge + post-checkout on 246 repo):
   auto re-link after git operations
3. Manual fallback: sync_profile_scripts.sh (now self-logging)

dev-spec red line #6 updated: SSOT rule now documents the three layers
and states breakage only happens at deploy time.
This commit is contained in:
hmo
2026-07-20 20:27:11 +08:00
parent 08eef1e181
commit 9a359f49bd
7 changed files with 221 additions and 2 deletions
+9
View File
@@ -0,0 +1,9 @@
[Unit]
Description=Watch deploy/profile-scripts for changes and re-sync hardlinks
[Path]
PathChanged=/home/hmo/MoFin/deploy/profile-scripts
Unit=profile-scripts-sync.service
[Install]
WantedBy=multi-user.target
+7
View File
@@ -0,0 +1,7 @@
[Unit]
Description=Re-sync profile scripts hardlinks after deploy dir changes
[Service]
Type=oneshot
User=hmo
ExecStart=/bin/bash /home/hmo/MoFin/deploy/profile-scripts/sync_profile_scripts.sh
@@ -10,4 +10,7 @@ for f in "$SRC"/*.py; do
ln -f "$f" "$DST/$name"
count=$((count+1))
done
echo "synced $count scripts (hardlink)"
ln -f "$SRC/sync_profile_scripts.sh" "$DST/sync_profile_scripts.sh" 2>/dev/null || true
echo "synced $count scripts (hardlink)"
mkdir -p /home/hmo/MoFin/gateway/logs
echo "$(date '+%F %T') synced $count scripts" >> /home/hmo/MoFin/gateway/logs/link_sync.log