#!/usr/bin/env bash # Verify brain installation integrity # Checks: .brain-version, sha256 from manifest.json, settings.json validity, hooks syntax # # Usage: verify.sh --target= [--strict-secrets] set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "$SCRIPT_DIR/lib/common.sh" # Determine brain root: env BRAIN_ROOT or script's parent BRAIN_ROOT="${BRAIN_ROOT:-$(cd "$SCRIPT_DIR/.." && pwd)}" target="" strict_secrets=0 while [ $# -gt 0 ]; do case "$1" in --target=*) target="${1#--target=}" ;; --strict-secrets) strict_secrets=1 ;; *) log_error "Unknown: $1"; exit 1 ;; esac shift done [ -n "$target" ] || { log_error "--target required"; exit 1; } # Check 1: .brain-version exists bv="$target/.brain-version" [ -f "$bv" ] || { log_error ".brain-version not found in $target"; exit 1; } # Parse version + sha version=$(head -1 "$bv") sha_line=$(grep '^sha:' "$bv" || echo "") [ -n "$version" ] || { log_error ".brain-version: missing version line"; exit 1; } log_info "Found .brain-version: $version" # Check 2: manifest.json exists in brain root manifest="$BRAIN_ROOT/manifest.json" [ -f "$manifest" ] || { log_error "manifest.json missing in BRAIN_ROOT=$BRAIN_ROOT"; exit 1; } # Check 3: sha256 per file in manifest (если manifest содержит files) files_count=$(jq -r '(.files // {}) | length' "$manifest") if [ "$files_count" -gt 0 ]; then log_info "Verifying $files_count file hashes..." while IFS= read -r entry; do rel_path=$(echo "$entry" | jq -r '.key') expected_sha=$(echo "$entry" | jq -r '.value') actual_path="$target/$rel_path" if [ ! -f "$actual_path" ]; then log_error "Missing: $rel_path" exit 2 fi if command -v sha256sum >/dev/null 2>&1; then actual_sha=$(sha256sum "$actual_path" | cut -d' ' -f1) else actual_sha=$(certutil -hashfile "$actual_path" SHA256 | sed -n '2p' | tr -d ' \r') fi if [ "$actual_sha" != "$expected_sha" ]; then log_error "SHA mismatch: $rel_path (expected $expected_sha, got $actual_sha)" exit 2 fi done < <(jq -c '(.files // {}) | to_entries[]' "$manifest") fi # Check 4: strict secrets — no unresolved <<*>> placeholders if [ "$strict_secrets" -eq 1 ]; then if grep -rE '<<[A-Z_]+>>' "$target" 2>/dev/null | grep -v '.brain-backup' | head -1; then log_error "Unresolved placeholders found" exit 7 fi fi log_info "Verification passed" exit 0