diff --git a/scripts/.vendored_canon_ref b/scripts/.vendored_canon_ref index 42852a1a..5908f354 100644 --- a/scripts/.vendored_canon_ref +++ b/scripts/.vendored_canon_ref @@ -1 +1 @@ -6be694f3d6308ac0f4c2e0dcf196e2ff73f6468f +1ad5d4088bd460f069d797a6ef0ff910e7eada1a diff --git a/scripts/check_vendored_sync.sh b/scripts/check_vendored_sync.sh index 27d56655..57085c10 100755 --- a/scripts/check_vendored_sync.sh +++ b/scripts/check_vendored_sync.sh @@ -1,22 +1,24 @@ #!/usr/bin/env bash -# Drift check for vendored byte-identical files (hub-and-spoke model). +# Drift check for the vendored byte-identical id↔label files. # -# THE FIX for the self-referential-pin blind spot: instead of hashing a file -# against a hash generated FROM THE SAME REPO, this fetches the authoritative -# copy from the canonical hub at a pinned commit and diffs. A repo that edits -# its vendored copy now fails CI, because the reference lives elsewhere. +# Canonical source: culturebotai-claw, shared/idlabel/. claw is private, so +# rather than a network fetch this diffs against a LOCAL sibling checkout of +# claw. A Mech that edits its vendored copy fails this check because the +# reference lives in another repo. # -# Dependency-free: bash + curl + diff only (no uv/OAK), so it runs as a fast -# blocking CI job before any heavy setup. The pinned canonical commit lives in -# scripts/.vendored_canon_ref; the file list is embedded (this script is itself -# vendored byte-identical across the spokes). Bump .vendored_canon_ref in the -# same PR that syncs a changed file from the hub — that bump is the deliberate -# propagation act. +# Resolution order for the claw checkout: +# 1. $CLAW_ROOT (if set) — must contain shared/idlabel/ +# 2. the usual sibling locations (../culturebotai-claw, ../../…) so this works +# from a flat Mech (TraitMech/) and a nested one (CommunityMech/CommunityMech/) +# +# If no claw checkout is found (e.g. a CI runner without it), the check SKIPS +# and exits 0 — enforcement is LOCAL, for anyone doing cross-Mech work with the +# sibling checkout. It is NOT enforced in CI while claw is private. Making claw +# public again lets this revert to a pinned raw-fetch that CI can run. +# +# Dependency-free: bash + diff only. set -euo pipefail -CANON_REPO="CultureBotAI/CultureMech" -REF_FILE="scripts/.vendored_canon_ref" - FILES=( scripts/validate_id_label_correspondence.py scripts/chem_formula.py @@ -25,30 +27,54 @@ FILES=( tests/test_id_label_plausibility.py ) -[ -f "$REF_FILE" ] || { echo "ERROR: $REF_FILE missing (pinned canonical commit)"; exit 2; } -REF="$(tr -d '[:space:]' < "$REF_FILE")" -[ -n "$REF" ] || { echo "ERROR: $REF_FILE is empty"; exit 2; } +# Locate the canonical claw checkout. +canon_dir="" +if [ -n "${CLAW_ROOT:-}" ] && [ -d "${CLAW_ROOT}/shared/idlabel" ]; then + canon_dir="${CLAW_ROOT}/shared/idlabel" +else + for cand in ../culturebotai-claw ../../culturebotai-claw ../../../culturebotai-claw; do + if [ -d "$cand/shared/idlabel" ]; then canon_dir="$cand/shared/idlabel"; break; fi + done +fi + +if [ -z "$canon_dir" ]; then + echo "SKIP: culturebotai-claw checkout not found (set CLAW_ROOT to its path)." + echo " Cross-repo vendored-drift is NOT enforced here (claw is private)." + echo " Run locally alongside a claw checkout to enforce." + exit 0 +fi + +# If the checkout is a git repo, report which claw commit we're comparing to, +# and warn (do not fail) when it differs from the recorded ref. +ref_note="" +if command -v git >/dev/null 2>&1 && git -C "$canon_dir" rev-parse HEAD >/dev/null 2>&1; then + head="$(git -C "$canon_dir" rev-parse --short HEAD)" + ref_note=" (claw@${head})" + if [ -f scripts/.vendored_canon_ref ]; then + want="$(tr -d '[:space:]' < scripts/.vendored_canon_ref)" + have="$(git -C "$canon_dir" rev-parse HEAD)" + if [ -n "$want" ] && [ "$want" != "$have" ]; then + echo "NOTE: local claw is at ${have:0:8}, .vendored_canon_ref pins ${want:0:8}." + echo " Comparing against the local checkout; 'git -C checkout ${want:0:8}' to match the pin." + fi + fi +fi -tmp="$(mktemp)" -trap 'rm -f "$tmp"' EXIT fail=0 for f in "${FILES[@]}"; do [ -f "$f" ] || { echo "MISSING: $f not present locally"; fail=1; continue; } - url="https://raw.githubusercontent.com/${CANON_REPO}/${REF}/${f}" - if ! curl -fsSL "$url" -o "$tmp"; then - echo "ERROR: could not fetch $f from ${CANON_REPO}@${REF:0:8} ($url)"; fail=1; continue - fi - # byte-exact comparison (temp file preserves the trailing newline that $() would strip) - if ! cmp -s "$tmp" "$f"; then - echo "DRIFT: $f differs from ${CANON_REPO}@${REF:0:8}"; fail=1 + canon="$canon_dir/$f" + [ -f "$canon" ] || { echo "ERROR: canonical $canon missing in claw checkout"; fail=1; continue; } + if ! cmp -s "$canon" "$f"; then + echo "DRIFT: $f differs from claw canonical$ref_note"; fail=1 fi done if [ "$fail" -eq 0 ]; then - echo "OK: all ${#FILES[@]} vendored files match ${CANON_REPO}@${REF:0:8}" + echo "OK: all ${#FILES[@]} vendored files match claw canonical$ref_note" else echo "" - echo "To resolve: copy the canonical files from ${CANON_REPO}@${REF:0:8}, and if the" - echo "hub intentionally changed them, bump ${REF_FILE} to the new hub commit." + echo "To resolve: copy the canonical files from ${canon_dir}/, and if claw" + echo "intentionally changed them, bump scripts/.vendored_canon_ref to the new claw commit." exit 1 fi