guanghu-ice-heart/modules/guanghu-panel-kit/hooks/pre-receive-review.template
冰朔 8544cae938 feat(modules): add guanghu-panel-kit reusable modules + two-system causal chain
光湖子系统面板模块包(胖头鱼/守望两系统沉淀):
- panel/server.js 配置驱动审批面板(登录门/签字/写入窗口/部署通道/唤醒导航)
- deploy/verify-and-deploy.py 部署校验Agent(地图/因果链/范围/完整性,0或100)
- hooks/pre-receive-review.template 推送审核钩子模板
- frontend 两套门面样例(湖绿深色/宠物暖色玻璃动态)
- CAUSAL-CHAIN-20260806.hdlp 两系统建设完整因果链
2026-08-06 21:21:58 +08:00

95 lines
3.7 KiB
Shell
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
# mm-review · maomao-fifth-domain pre-receive 自动审核 · 铸渊 2026-08-06
# ⊢ 明文密钥必拦 ⊢ 破坏现有必拦 ⊢ 写入窗口必验 ⊢ 每次写入留痕
LOG_DIR=/srv/guanghu/mm-gz-001/access/logs
GRANTS=/srv/guanghu/mm-gz-001/access/grants.json
PUSHER="${GITEA_PUSHER_NAME:-unknown}"
VERDICT=PASS
REASONS=()
COMMITS=0
REFSLIST=""
PUSHER_ATTR=""
ZERO=0000000000000000000000000000000000000000
mkdir -p "$LOG_DIR"
active_grant() {
python3 - "$GRANTS" <<'PY'
import json,sys,datetime
try: g=json.load(open(sys.argv[1]))
except Exception: print("none"); sys.exit()
now=datetime.datetime.now(datetime.timezone.utc)
for x in g:
if x.get("status")=="active":
try: exp=datetime.datetime.fromisoformat(x["expiresAt"])
except Exception: continue
if exp>now: print(x.get("persona","persona")); sys.exit()
print("none")
PY
}
while read -r old new ref; do
REFSLIST="$REFSLIST $ref"
branch=${ref#refs/heads/}
if [ "$new" = "$ZERO" ]; then
case "$branch" in
guanghu/main|deploy) VERDICT=REJECT; REASONS+=("禁止删除受保护分支: $branch");;
esac
continue
fi
if [ "$PUSHER" = "mm-writer" ]; then
W=$(active_grant)
if [ "$W" = "none" ]; then
VERDICT=REJECT
REASONS+=("无有效写入窗口3小时授权已过期或未申请。人格体请先 POST https://maomao.guanghulab.com/api/access-request 申请,等苍耳审批")
continue
fi
PUSHER_ATTR="$W"
fi
if [ "$old" != "$ZERO" ]; then
if ! git merge-base --is-ancestor "$old" "$new" 2>/dev/null; then
VERDICT=REJECT; REASONS+=("禁止历史重写(非快进推送): $branch")
continue
fi
fi
for c in $(git rev-list "$old".."$new" 2>/dev/null || git rev-list -n 20 "$new" 2>/dev/null); do
COMMITS=$((COMMITS+1))
for f in $(git diff-tree --root --no-commit-id --name-only --diff-filter=AM -r "$c" 2>/dev/null | head -60); do
if git show "$c:$f" 2>/dev/null | head -c 400000 | grep -qE "sk-[A-Za-z0-9]{16,}|AKIA[A-Z0-9]{16}|-----BEGIN [A-Z ]*PRIVATE KEY-----|gh[pousr]_[A-Za-z0-9]{20,}|xox[baprs]-[A-Za-z0-9-]{10,}|(api[_-]?key|apikey|secret[_-]?key|access[_-]?token|password|passwd)[\"']?[[:space:]]*[:=][[:space:]]*[\"'][A-Za-z0-9+/=_.-]{12,}"; then
VERDICT=REJECT; REASONS+=("文件疑似包含明文密钥: $f(提交 ${c:0:8})。密钥必须移出仓库")
fi
done
if [ "$PUSHER" != "maomao" ]; then
for f in $(git diff-tree --root --no-commit-id --name-only --diff-filter=D -r "$c" 2>/dev/null); do
case "$f" in
REPO-MAP.hdlp|GLW-ENTRY.hdlp|INDEX.hdlp|README.md|AGENTS.md|guanghu-nodes/MM-GZ-001/machine/NAVIGATION.json|guanghu-nodes/MM-GZ-001/recovery/WAKE-UP-ROUTE.json|guanghu-nodes/MM-GZ-001/personas/registry.json)
VERDICT=REJECT; REASONS+=("人格体不得删除入口文件: $f");;
esac
done
fi
done
done
python3 - "$LOG_DIR" "$PUSHER" "$PUSHER_ATTR" "$VERDICT" "$COMMITS" "$REFSLIST" "$(printf '%s|' "${REASONS[@]}")" <<'PY'
import json,sys,datetime,os
logdir,pusher,attr,verdict,commits,refs,reasons=sys.argv[1:8]
rec={"ts":datetime.datetime.now(datetime.timezone.utc).isoformat(),
"pusher":pusher,"persona":attr or None,"verdict":verdict,
"commits":int(commits),"refs":refs.split(),
"reasons":[r for r in reasons.split("|") if r]}
os.makedirs(logdir,exist_ok=True)
p=os.path.join(logdir,"PUSH-%s.json"%datetime.datetime.now().strftime("%Y%m%dT%H%M%S%f"))
open(p,"w").write(json.dumps(rec,ensure_ascii=False,indent=1))
PY
if [ "$VERDICT" = "REJECT" ]; then
echo "── 守望自动审核REJECT ──"
for r in "${REASONS[@]}"; do echo "$r"; done
exit 1
fi
echo "── 守望自动审核PASS$COMMITS 提交 · 推送者 $PUSHER${PUSHER_ATTR:+ · 人格 $PUSHER_ATTR})──"
exit 0