铸澜 + 冰朔 · 固化记忆导航门禁部署链
This commit is contained in:
parent
e7cec83b38
commit
7f405f9dd3
@ -23,9 +23,11 @@ echo ""
|
|||||||
# 1. 创建钩子目录
|
# 1. 创建钩子目录
|
||||||
mkdir -p "${FORGEJO_HOOK_DIR}"
|
mkdir -p "${FORGEJO_HOOK_DIR}"
|
||||||
|
|
||||||
# 2. 复制审计脚本
|
# 2. 复制服务器守门人及其导航依赖
|
||||||
cp pre-receive-guard.py "${FORGEJO_HOOK_DIR}/${SCRIPT_NAME}"
|
cp pre-receive-guard.py "${FORGEJO_HOOK_DIR}/${SCRIPT_NAME}"
|
||||||
chmod +x "${FORGEJO_HOOK_DIR}/${SCRIPT_NAME}"
|
chmod +x "${FORGEJO_HOOK_DIR}/${SCRIPT_NAME}"
|
||||||
|
cp navigation-memory-guard.py "${FORGEJO_HOOK_DIR}/navigation-memory-guard.py"
|
||||||
|
chmod +x "${FORGEJO_HOOK_DIR}/navigation-memory-guard.py"
|
||||||
|
|
||||||
# 3. 创建钩子包装器(Forgejo 调用这个 shell 脚本 → 内部调 Python)
|
# 3. 创建钩子包装器(Forgejo 调用这个 shell 脚本 → 内部调 Python)
|
||||||
cat > "${FORGEJO_HOOK_DIR}/${HOOK_NAME}" << 'WRAPPER'
|
cat > "${FORGEJO_HOOK_DIR}/${HOOK_NAME}" << 'WRAPPER'
|
||||||
|
|||||||
@ -16,14 +16,16 @@ fi
|
|||||||
|
|
||||||
HOOK_DIR="$REPO_ROOT/.git/hooks"
|
HOOK_DIR="$REPO_ROOT/.git/hooks"
|
||||||
PLUGIN_SRC="$REPO_ROOT/zero-point/core-channel/revive-guard/pre-push-clean.py"
|
PLUGIN_SRC="$REPO_ROOT/zero-point/core-channel/revive-guard/pre-push-clean.py"
|
||||||
|
NAVIGATION_GUARD_SRC="$REPO_ROOT/zero-point/core-channel/revive-guard/navigation-memory-guard.py"
|
||||||
PLUGIN_DST="$HOOK_DIR/pre-push"
|
PLUGIN_DST="$HOOK_DIR/pre-push"
|
||||||
|
NAVIGATION_GUARD_DST="$HOOK_DIR/navigation-memory-guard.py"
|
||||||
|
|
||||||
echo "🛡️ 光湖 pre-push-clean 插件安装"
|
echo "🛡️ 光湖 pre-push-clean 插件安装"
|
||||||
echo " 仓库: $(basename "$REPO_ROOT")"
|
echo " 仓库: $(basename "$REPO_ROOT")"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# 1. 检查源文件
|
# 1. 检查源文件
|
||||||
if [ ! -f "$PLUGIN_SRC" ]; then
|
if [ ! -f "$PLUGIN_SRC" ] || [ ! -f "$NAVIGATION_GUARD_SRC" ]; then
|
||||||
echo "❌ 找不到 $PLUGIN_SRC"
|
echo "❌ 找不到 $PLUGIN_SRC"
|
||||||
echo " 请确保在 fifth-domain 仓库根目录下执行"
|
echo " 请确保在 fifth-domain 仓库根目录下执行"
|
||||||
exit 1
|
exit 1
|
||||||
@ -42,6 +44,8 @@ fi
|
|||||||
# 4. 安装插件
|
# 4. 安装插件
|
||||||
cp "$PLUGIN_SRC" "$PLUGIN_DST"
|
cp "$PLUGIN_SRC" "$PLUGIN_DST"
|
||||||
chmod +x "$PLUGIN_DST"
|
chmod +x "$PLUGIN_DST"
|
||||||
|
cp "$NAVIGATION_GUARD_SRC" "$NAVIGATION_GUARD_DST"
|
||||||
|
chmod +x "$NAVIGATION_GUARD_DST"
|
||||||
|
|
||||||
# 5. 验证
|
# 5. 验证
|
||||||
echo ""
|
echo ""
|
||||||
|
|||||||
@ -5,15 +5,24 @@ This guard is deliberately structural: it does not judge prose. It verifies
|
|||||||
that a new/changed durable memory leaf has the minimum HLDP recovery fields
|
that a new/changed durable memory leaf has the minimum HLDP recovery fields
|
||||||
and can be reached from a current navigation page.
|
and can be reached from a current navigation page.
|
||||||
"""
|
"""
|
||||||
import os, re, subprocess, sys
|
import os, subprocess, sys
|
||||||
|
|
||||||
REQUIRED = ("trigger:", "emergence:", "lock:", "why:", "checkpoint")
|
REQUIRED = ("trigger:", "emergence:", "lock:", "why:", "checkpoint")
|
||||||
NAVIGATION = ("INDEX.hdlp", "CURRENT.hdlp", "LL-CURRENT.hdlp", "BROADCAST-TOWER.hdlp")
|
NAVIGATION = ("INDEX.hdlp", "CURRENT.hdlp", "LL-CURRENT.hdlp", "BROADCAST-TOWER.hdlp")
|
||||||
|
|
||||||
def changed_files():
|
def changed_files():
|
||||||
|
"""Return candidate files for a local check or a server receive range."""
|
||||||
|
if len(sys.argv) == 3 and sys.argv[1] == "--range":
|
||||||
|
old_rev, new_rev = sys.argv[2].split("..", 1)
|
||||||
|
if old_rev == "0" * 40:
|
||||||
|
command = ["git", "diff-tree", "--no-commit-id", "-r", "--name-only", "--diff-filter=ACM", new_rev]
|
||||||
|
else:
|
||||||
|
command = ["git", "diff", "--name-only", "--diff-filter=ACM", old_rev, new_rev]
|
||||||
|
result = subprocess.run(command, capture_output=True, text=True)
|
||||||
|
return sorted(x for x in result.stdout.splitlines() if x) if result.returncode == 0 else []
|
||||||
|
|
||||||
commands = [
|
commands = [
|
||||||
["git", "diff", "--cached", "--name-only", "--diff-filter=ACM"],
|
["git", "diff", "--cached", "--name-only", "--diff-filter=ACM"],
|
||||||
["git", "diff", "--name-only", "HEAD~1", "HEAD", "--diff-filter=ACM"],
|
|
||||||
]
|
]
|
||||||
files = set()
|
files = set()
|
||||||
for cmd in commands:
|
for cmd in commands:
|
||||||
|
|||||||
@ -170,6 +170,7 @@ def main():
|
|||||||
|
|
||||||
all_findings = []
|
all_findings = []
|
||||||
rejected = False
|
rejected = False
|
||||||
|
navigation_guard = os.path.join(os.path.dirname(os.path.abspath(__file__)), "navigation-memory-guard.py")
|
||||||
|
|
||||||
for line in sys.stdin:
|
for line in sys.stdin:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
@ -184,6 +185,19 @@ def main():
|
|||||||
if new_rev == "GIT_TOKEN_REDACTED":
|
if new_rev == "GIT_TOKEN_REDACTED":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# 持续记忆必须先通过结构门禁;服务器使用本次 receive 的精确提交范围,
|
||||||
|
# 不依赖工作树,也不会扫描上一笔无关提交。
|
||||||
|
if os.path.isfile(navigation_guard):
|
||||||
|
navigation = subprocess.run(
|
||||||
|
[sys.executable, navigation_guard, "--range", f"{old_rev}..{new_rev}"],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=15,
|
||||||
|
)
|
||||||
|
if navigation.returncode != 0:
|
||||||
|
print(navigation.stderr or navigation.stdout, file=sys.stderr)
|
||||||
|
sys.exit(navigation.returncode)
|
||||||
|
|
||||||
# 获取新增/修改的文件列表
|
# 获取新增/修改的文件列表
|
||||||
try:
|
try:
|
||||||
# 先检查 commit message 是否含 [SEC-CLEAN] 标记
|
# 先检查 commit message 是否含 [SEC-CLEAN] 标记
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user