blob: 8fb9ab07f55897cbe31066ba771b88a3764ffa94 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
#!/usr/bin/env bash
#
# sync-check.sh — verify canonical claude-templates/.ai/ matches the .ai/ mirror.
#
# Usage:
# scripts/sync-check.sh # exit 0 if synced, 1 if drift
# scripts/sync-check.sh --fix # rsync canonical → mirror, then re-check
#
# Runs as a pre-commit hook (githooks/pre-commit) to catch drift before
# commit, and as a manual check via `make sync-check`.
#
# The three synced paths are:
# claude-templates/.ai/protocols.org ↔ .ai/protocols.org
# claude-templates/.ai/workflows/ ↔ .ai/workflows/
# claude-templates/.ai/scripts/ ↔ .ai/scripts/
#
# Source of truth is the canonical (claude-templates/) side. The mirror
# exists so rulesets-as-a-project has a working copy. Drift in either
# direction is a defect — both have to land in the same commit.
set -euo pipefail
if ! repo_root="$(git rev-parse --show-toplevel 2>/dev/null)" || [ -z "$repo_root" ]; then
echo "sync-check: not inside a git checkout" >&2
exit 2
fi
canonical="$repo_root/claude-templates/.ai"
mirror="$repo_root/.ai"
if [ ! -d "$canonical" ] || [ ! -d "$mirror" ]; then
echo "sync-check: not a rulesets-shaped repo (missing claude-templates/.ai or .ai)" >&2
exit 2
fi
paths=(protocols.org workflows scripts)
check_drift() {
local drift=0
for relpath in "${paths[@]}"; do
if ! diff -rq "$canonical/$relpath" "$mirror/$relpath" >/dev/null 2>&1; then
echo "drift: claude-templates/.ai/$relpath ↔ .ai/$relpath" >&2
diff -rq "$canonical/$relpath" "$mirror/$relpath" 2>&1 | head -20 >&2
drift=1
fi
done
return "$drift"
}
if check_drift; then
exit 0
fi
if [ "${1:-}" = "--fix" ]; then
echo "" >&2
echo "sync-check --fix: syncing canonical → mirror..." >&2
rsync -a "$canonical/protocols.org" "$mirror/protocols.org"
rsync -a --delete "$canonical/workflows/" "$mirror/workflows/"
rsync -a --delete "$canonical/scripts/" "$mirror/scripts/"
if check_drift; then
echo "sync-check --fix: resolved." >&2
echo "Re-stage the synced files and retry the commit." >&2
exit 0
else
echo "sync-check --fix: drift persists after sync. Inspect manually." >&2
exit 1
fi
fi
echo "" >&2
echo "Run 'scripts/sync-check.sh --fix' (or 'make sync-check FIX=1') to resolve." >&2
exit 1
|