#!/usr/bin/env bash set -euo pipefail source "$(dirname "$0")/../scripts/lib/common.sh" require_cmd jq EVID_DIR="${1:?usage: governance_constitution_pinned.sh }" TS="$(iso_utc_now)" FILE="$EVID_DIR/constitution_hash.json" ROOT="$(vmcc_root)" PIN_FILE="${VMCC_PINS_FILE:-$ROOT/config/pins.yaml}" PINNED_SHA256="${VMCC_PINNED_CONSTITUTION_SHA256:-}" if [[ -z "$PINNED_SHA256" && -f "$PIN_FILE" ]]; then PINNED_SHA256="$(awk -F': *' '/^constitution_sha256:/ {print $2}' "$PIN_FILE" | tr -d '"' | tr -d "'" | head -n 1)" fi if [[ ! -f "$FILE" ]]; then json_emit "$(jq -n --arg ts "$TS" '{ version:"1.0.0", rule_id:"governance.constitution_pinned", control_ids:["GV-01"], passed:false, severity:"HIGH", timestamp:$ts, evidence:[{path:"constitution_hash.json"}], details:{error:"missing evidence file"} }')" exit 0 fi COLLECTED="$(jq -r '.collected // false' "$FILE")" if [[ "$COLLECTED" != "true" ]]; then json_emit "$(jq -n --arg ts "$TS" '{ version:"1.0.0", rule_id:"governance.constitution_pinned", control_ids:["GV-01"], passed:false, severity:"HIGH", timestamp:$ts, evidence:[{path:"constitution_hash.json"}], details:{error:"constitution hash not collected"} }')" exit 0 fi OBSERVED="$(jq -r '.sha256 // empty' "$FILE")" if [[ -z "$PINNED_SHA256" ]]; then json_emit "$(jq -n --arg ts "$TS" --arg observed "$OBSERVED" '{ version:"1.0.0", rule_id:"governance.constitution_pinned", control_ids:["GV-01"], passed:false, severity:"HIGH", timestamp:$ts, evidence:[{path:"constitution_hash.json"}], details:{error:"no pinned hash configured", observed_sha256:$observed} }')" exit 0 fi if [[ "$OBSERVED" == "$PINNED_SHA256" ]]; then json_emit "$(jq -n --arg ts "$TS" '{ version:"1.0.0", rule_id:"governance.constitution_pinned", control_ids:["GV-01"], passed:true, severity:"HIGH", timestamp:$ts, evidence:[{path:"constitution_hash.json"}], details:{} }')" else json_emit "$(jq -n --arg ts "$TS" --arg observed "$OBSERVED" --arg pinned "$PINNED_SHA256" '{ version:"1.0.0", rule_id:"governance.constitution_pinned", control_ids:["GV-01"], passed:false, severity:"HIGH", timestamp:$ts, evidence:[{path:"constitution_hash.json"}], details:{error:"hash mismatch", observed_sha256:$observed, pinned_sha256:$pinned} }')" fi