sync: auto-sync from GURU-5070 at 2026-06-08 07:42:44
Author: Mike Swanson Machine: GURU-5070 Timestamp: 2026-06-08 07:42:44
This commit is contained in:
@@ -10,3 +10,10 @@ or old harness during a heterogeneous rollout. See
|
|||||||
- Task 0.6: out-of-band recovery script `.claude/scripts/force-pull-raw.sh` added.
|
- Task 0.6: out-of-band recovery script `.claude/scripts/force-pull-raw.sh` added.
|
||||||
- (Earlier) Syncro billing SSOT resolved: `add_line_item` is normal billing; timers are
|
- (Earlier) Syncro billing SSOT resolved: `add_line_item` is normal billing; timers are
|
||||||
outlier-only (explicit request).
|
outlier-only (explicit request).
|
||||||
|
|
||||||
|
## 1.1.0 — 2026-06-08
|
||||||
|
- Task 1: submodule-safe sync — `sync.sh` now unstages submodule gitlinks (unless
|
||||||
|
`--with-submodules`), eliminating the manual detach-to-pin dance before /save.
|
||||||
|
- Task 4: `harness-guard.sh` wired into `sync.sh` pre-commit, WARN-ONLY (logs conflict
|
||||||
|
markers / unencrypted sops / private keys to .claude/harness/guard.log; does not block
|
||||||
|
unless HARNESS_GUARD_FATAL=1; SKIP_HARNESS_GUARD=1 bypasses).
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
1.0.0
|
1.1.0
|
||||||
|
|||||||
63
.claude/scripts/harness-guard.sh
Normal file
63
.claude/scripts/harness-guard.sh
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Harness commit guard. Inspects STAGED content for footguns before a commit.
|
||||||
|
#
|
||||||
|
# Rollout posture: WARN-ONLY by default (logs + prints, never blocks). This is
|
||||||
|
# deliberate (Task 4): a guard that fails closed can brick every machine's /save. It is
|
||||||
|
# promoted to blocking only after a clean warn window across the fleet.
|
||||||
|
# - default -> warn only, exit 0
|
||||||
|
# - HARNESS_GUARD_FATAL=1 -> exit 1 on any issue (caller decides to abort)
|
||||||
|
# - SKIP_HARNESS_GUARD=1 -> bypass entirely (logged)
|
||||||
|
# Detects: conflict markers, unencrypted SOPS / private-key material, and a staged
|
||||||
|
# submodule gitlink change (informational).
|
||||||
|
set -uo pipefail
|
||||||
|
|
||||||
|
ROOT=$(git rev-parse --show-toplevel 2>/dev/null) || exit 0
|
||||||
|
cd "$ROOT"
|
||||||
|
LOG="$ROOT/.claude/harness/guard.log"
|
||||||
|
mkdir -p "$(dirname "$LOG")" 2>/dev/null || true
|
||||||
|
ts() { date '+%Y-%m-%dT%H:%M:%S' 2>/dev/null || echo "?"; }
|
||||||
|
warn() { echo "[harness-guard][WARN] $1"; echo "$(ts) WARN $1" >> "$LOG" 2>/dev/null || true; }
|
||||||
|
|
||||||
|
if [ "${SKIP_HARNESS_GUARD:-0}" = "1" ]; then
|
||||||
|
echo "[harness-guard] bypassed (SKIP_HARNESS_GUARD=1)"
|
||||||
|
echo "$(ts) BYPASS SKIP_HARNESS_GUARD=1" >> "$LOG" 2>/dev/null || true
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
ISSUES=0
|
||||||
|
mapfile -t STAGED < <(git diff --cached --name-only --diff-filter=ACM 2>/dev/null)
|
||||||
|
|
||||||
|
for f in "${STAGED[@]}"; do
|
||||||
|
[ -n "$f" ] || continue
|
||||||
|
blob=$(git show ":$f" 2>/dev/null) || continue
|
||||||
|
# 1. Conflict markers
|
||||||
|
if printf '%s\n' "$blob" | grep -qE '^(<<<<<<< |=======$|>>>>>>> )'; then
|
||||||
|
warn "conflict markers in staged file: $f"; ISSUES=$((ISSUES + 1))
|
||||||
|
fi
|
||||||
|
# 2. Unencrypted SOPS vault file
|
||||||
|
case "$f" in
|
||||||
|
*.sops.yaml|*.sops.json|*.sops.env)
|
||||||
|
if ! printf '%s\n' "$blob" | grep -qE 'ENC\[|^sops:'; then
|
||||||
|
warn "possible UNENCRYPTED sops file staged: $f"; ISSUES=$((ISSUES + 1))
|
||||||
|
fi ;;
|
||||||
|
esac
|
||||||
|
# 3. Private key material
|
||||||
|
if printf '%s\n' "$blob" | grep -qE -- '-----BEGIN [A-Z ]*PRIVATE KEY-----'; then
|
||||||
|
warn "private-key material in staged file: $f"; ISSUES=$((ISSUES + 1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# 4. Submodule gitlink staged (informational — should only happen with --with-submodules)
|
||||||
|
if git diff --cached --submodule=short 2>/dev/null | grep -q '^Submodule '; then
|
||||||
|
warn "submodule gitlink change is staged (intentional only via --with-submodules)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$ISSUES" -gt 0 ]; then
|
||||||
|
echo "[harness-guard] $ISSUES issue(s) found."
|
||||||
|
if [ "${HARNESS_GUARD_FATAL:-0}" = "1" ]; then
|
||||||
|
echo "[harness-guard] FATAL mode -> signalling block."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "[harness-guard] WARN-ONLY mode -> not blocking."
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
@@ -323,6 +323,18 @@ if [ -n "$(git status --porcelain)" ]; then
|
|||||||
purge_garbled_paths
|
purge_garbled_paths
|
||||||
git add -A
|
git add -A
|
||||||
|
|
||||||
|
# Submodule-safe staging (Task 1): `git add -A` stages submodule gitlink (pointer)
|
||||||
|
# changes. The parent's pinned commit intentionally lags the submodule's main, so
|
||||||
|
# auto-committing the pointer bumps a possibly-stale gitlink. Unstage every submodule
|
||||||
|
# gitlink unless the operator opted in with --with-submodules. This eliminates the
|
||||||
|
# manual "detach submodule to its pin before /save" dance.
|
||||||
|
if [ "${ADVANCE_SUBMODULES:-0}" != "1" ] && [ -f ".gitmodules" ]; then
|
||||||
|
while IFS= read -r sm_path; do
|
||||||
|
[ -n "$sm_path" ] || continue
|
||||||
|
git reset -q HEAD -- "$sm_path" 2>/dev/null || true
|
||||||
|
done < <(git config --file .gitmodules --get-regexp '^submodule\..*\.path$' | awk '{print $2}')
|
||||||
|
fi
|
||||||
|
|
||||||
# Commit message (Co-Authored-By uses local git user if configured)
|
# Commit message (Co-Authored-By uses local git user if configured)
|
||||||
COMMIT_MSG="sync: auto-sync from $MACHINE at $TIMESTAMP
|
COMMIT_MSG="sync: auto-sync from $MACHINE at $TIMESTAMP
|
||||||
|
|
||||||
@@ -331,10 +343,19 @@ Machine: $MACHINE
|
|||||||
Timestamp: $TIMESTAMP"
|
Timestamp: $TIMESTAMP"
|
||||||
|
|
||||||
if git diff-index --quiet --cached HEAD -- 2>/dev/null; then
|
if git diff-index --quiet --cached HEAD -- 2>/dev/null; then
|
||||||
echo -e "${GREEN}[OK]${NC} No stageable changes (submodule internal changes skipped)."
|
echo -e "${GREEN}[OK]${NC} No stageable changes (submodule pointer + internal changes skipped)."
|
||||||
else
|
else
|
||||||
git commit -m "$COMMIT_MSG"
|
# Harness guard (Task 4): WARN-ONLY during rollout — logs footguns (conflict
|
||||||
echo -e "${GREEN}[OK]${NC} Committed."
|
# markers, unencrypted sops, private-key material) to .claude/harness/guard.log
|
||||||
|
# but does NOT block unless HARNESS_GUARD_FATAL=1. SKIP_HARNESS_GUARD=1 bypasses.
|
||||||
|
GUARD_RC=0
|
||||||
|
bash .claude/scripts/harness-guard.sh || GUARD_RC=$?
|
||||||
|
if [ "$GUARD_RC" != "0" ]; then
|
||||||
|
echo -e "${YELLOW}[WARNING]${NC} harness-guard blocked the commit (HARNESS_GUARD_FATAL set). Staged changes left in place; set SKIP_HARNESS_GUARD=1 to override."
|
||||||
|
else
|
||||||
|
git commit -m "$COMMIT_MSG"
|
||||||
|
echo -e "${GREEN}[OK]${NC} Committed."
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
echo -e "${GREEN}[OK]${NC} No local changes to commit."
|
echo -e "${GREEN}[OK]${NC} No local changes to commit."
|
||||||
|
|||||||
Reference in New Issue
Block a user