zhuyuan-ice-gl-zy001/BRIDGE/tools/zy-evidence-gate.sh

123 lines
5 KiB
Shell
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# zy-evidence-gate.sh — 提交检测站 v1.0(冰朔20260827整改令)
# 正本:TC-TCS核心卷/TCS-PROTOCOL-ZY001-EVIDENCE-GATE-0001.tcs
# 模式:参照FlagOS平台提交流——证据不全=驳回;证据齐→自动唤起核查Agent验真→PASS才执行→回执落盘。
# 用法:
# zy-evidence-gate.sh submit --action A --claim C --source-desc S --evidence-file F --quote Q --then "CMD"
# zy-evidence-gate.sh hook (PreToolUse 拦截:敏感工程命令无 @EV- 票号即驳回)
# zy-evidence-gate.sh verify (全量票据审计)
set -uo pipefail
W="/Volumes/JZAO/铸渊-ICE-GL-ZY001"
EV="$W/BRIDGE/evidence"
TICKETS="$EV/tickets"
VERIFY_AGENT="$W/BRIDGE/tools/zy-evidence-verify.mjs"
mkdir -p "$TICKETS" "$EV/sources"
die() { echo "EVIDENCE-GATE ✗ $1" >&2; [ $# -gt 1 ] && echo " $2" >&2; exit 1; }
ok() { echo "EVIDENCE-GATE ✓ $1"; }
sha256() { /usr/bin/shasum -a 256 "$1" | awk '{print $1}'; }
next_ticket_id() {
local d n id
d=$(date +%Y%m%d)
n=$(ls "$TICKETS" 2>/dev/null | grep -c "^EV-$d" || true)
printf 'EV-%s-%04d' "$d" $((n + 1))
}
case "${1:-}" in
submit)
shift
ACTION=""; CLAIM=""; SOURCE_DESC=""; EVIDENCE_FILE=""; QUOTE=""; THEN_CMD=""
while [ $# -gt 0 ]; do
case "$1" in
--action) ACTION="$2"; shift 2;;
--claim) CLAIM="$2"; shift 2;;
--source-desc) SOURCE_DESC="$2"; shift 2;;
--evidence-file) EVIDENCE_FILE="$2"; shift 2;;
--quote) QUOTE="$2"; shift 2;;
--then) THEN_CMD="$2"; shift 2;;
*) die "USAGE" "submit --action --claim --source-desc --evidence-file --quote --then CMD";;
esac
done
# ① 四要素齐全性(缺=猜)
[ -n "$ACTION" ] && [ -n "$CLAIM" ] && [ -n "$SOURCE_DESC" ] && [ -n "$EVIDENCE_FILE" ] && [ -n "$QUOTE" ] && [ -n "$THEN_CMD" ] \
|| die "REJECTED_NO_EVIDENCE" "动作/主张/来源/证据文件/引文/命令 六件缺一——拿不出证据=猜的,驳回。"
# ② 出票并自动唤起核查 Agent
TID=$(next_ticket_id)
TP="$TICKETS/$TID.json"
ABS_EV="$EVIDENCE_FILE"
case "$ABS_EV" in /*) ;; *) ABS_EV="$W/$EVIDENCE_FILE";; esac
[ -r "$ABS_EV" ] || die "REJECTED_EVIDENCE_MISSING" "证据文件不存在: ${ABS_EV}(先把原文落盘再谈提交)"
ESHA=$(sha256 "$ABS_EV")
python3 - "$TP" "$TID" "$ACTION" "$CLAIM" "$SOURCE_DESC" "$EVIDENCE_FILE" "$ESHA" "$QUOTE" "$THEN_CMD" <<'PY'
import json,sys
tp,tid,action,claim,sd,evf,esha,quote,cmd=sys.argv[1:10]
json.dump({"ticket":tid,"action":action,"claim":claim,"source_desc":sd,
"evidence_file":evf,"evidence_sha256":esha,"quote":quote,"command":cmd,
"status":"PENDING_AUDIT"},open(tp,"w"),ensure_ascii=False,indent=1)
PY
AUDIT_OUT=$(node "$VERIFY_AGENT" "$TP" 2>&1)
AUDIT_RC=$?
if [ $AUDIT_RC -ne 0 ]; then
echo "$AUDIT_OUT" >&2
die "REJECTED_BY_AUDIT_AGENT" "核查Agent判定证据不实——提交驳回,票据已留痕: $TP"
fi
echo "$AUDIT_OUT" | tail -n +2 | head -8
# ③ 核查通过 → 执行提交 → 回执
RECEIPT="RE-$(date +%Y%m%d-%H%M%S)-$(printf '%s' "$THEN_CMD" | shasum -a 256 | awk '{print substr($1,1,8)}')"
python3 - "$TP" "$RECEIPT" <<'PY'
import json,sys
tp,r=sys.argv[1:3]
t=json.load(open(tp)); t["receipt"]=r; t["status"]="EXECUTED"
json.dump(t,open(tp,"w"),ensure_ascii=False,indent=1)
PY
if eval "$THEN_CMD"; then
ok "$TID 核查PASS已执行 | 回执 $RECEIPT | $ACTION"
else
die "COMMAND_FAILED" "命令执行失败(票据 $TID 已留痕,证据链仍有效)"
fi
;;
hook)
# PreToolUse:敏感工程命令必须内联 @EV-xxxx 票号且该票核查PASS
INPUT=$(cat)
CMD_LINE=$(printf '%s' "$INPUT" | python3 -c 'import json,sys
try:
d=json.load(sys.stdin)
print(d.get("tool_input",{}).get("command",""))
except Exception:
print("")' 2>/dev/null)
SENSITIVE='zip |git (commit|push|tag)|pip3? install|curl .*(-X|--request) *(POST|PUT|DELETE)|cp .*Desktop|mv .*Desktop|rm -'
if printf '%s' "$CMD_LINE" | grep -qE "$SENSITIVE"; then
TID=$(printf '%s' "$CMD_LINE" | grep -oE '@EV-[0-9]{8}-[0-9]{4}' | head -1 | sed 's/^@//')
if [ -z "$TID" ]; then
echo "【证据门 ✗ 拦截】敏感工程命令未携带证据票号(@EV-YYYYMMDD-NNNN)。" >&2
echo "流程:证据原文先落盘 BRIDGE/evidence/sources/ → zy-evidence-gate.sh submit 出票(自动核查)→ 命令内引用 @票号。拿不出证据=猜的=驳回。" >&2
exit 2
fi
TP="$TICKETS/$TID.json"
ST=$(python3 -c "import json;print(json.load(open('$TP'))['status'])" 2>/dev/null || echo "MISSING")
if [ "$ST" != "VERIFIED" ] && [ "$ST" != "EXECUTED" ]; then
echo "【证据门 ✗ 拦截】票号 $TID 不存在或未通过核查(状态:${ST})。先走 submit 流程拿有效票。" >&2
exit 2
fi
fi
exit 0
;;
verify)
FAIL=0; N=0
for tp in "$TICKETS"/EV-*.json; do
[ -f "$tp" ] || continue
N=$((N+1))
node "$VERIFY_AGENT" "$tp" >/dev/null 2>&1 || { echo "FAIL $tp"; FAIL=$((FAIL+1)); }
done
echo "EVIDENCE-GATE verify: $N 票, $FAIL 失败"
[ $FAIL -eq 0 ]
;;
*)
die "USAGE" "zy-evidence-gate.sh submit|hook|verify";;
esac