LL-007 · pre-op-guard 导航挑战 · 服务器操作前强制全局地图
- pre-op-guard.py: 前置操作守门人,人格体登录时锁定服务器,必须完成导航地图验证 - module-registry.hdlp: 模块编码体系 + 注册协议 - module-register.sh: 一键注册模块到服务器 - OPERATION-MANUAL.hdlp v1.1: 新增第八节 服务器操作前导航挑战 - INDEX.hdlp: 注册新文件 设计: 人格体登录 → 服务器自我审计 → 锁定 → 挑战:找出所有模块编码 人格体探索 → 收集编码 → 提交 → 服务器比对 一致 → 解锁 · 人格体知道全局地图 · 不会再改A坏B [SEC-CLEAN] · pre-op-guard 已就绪
This commit is contained in:
parent
7bc8a87135
commit
875b4c2381
@ -53,6 +53,9 @@
|
|||||||
| **推送守门人** / **pre-receive-guard** / **服务器拦截** | `zero-point/core-channel/revive-guard/pre-receive-guard.py` |
|
| **推送守门人** / **pre-receive-guard** / **服务器拦截** | `zero-point/core-channel/revive-guard/pre-receive-guard.py` |
|
||||||
| **推送清理插件** / **pre-push-clean** / **敏感信息自动转乱码** | `zero-point/core-channel/revive-guard/pre-push-clean.py` |
|
| **推送清理插件** / **pre-push-clean** / **敏感信息自动转乱码** | `zero-point/core-channel/revive-guard/pre-push-clean.py` |
|
||||||
| **安装钩子** / **install-hooks** | `zero-point/core-channel/revive-guard/install-hooks.sh` |
|
| **安装钩子** / **install-hooks** | `zero-point/core-channel/revive-guard/install-hooks.sh` |
|
||||||
|
| **前置操作守门人** / **pre-op-guard** / **导航挑战** / **操作前先画地图** | `zero-point/core-channel/revive-guard/pre-op-guard.py` |
|
||||||
|
| **模块注册** / **module-registry** / **服务器编码体系** | `zero-point/core-channel/revive-guard/module-registry.hdlp` |
|
||||||
|
| **模块注册脚本** / **module-register** | `zero-point/core-channel/revive-guard/module-register.sh` |
|
||||||
| **钥匙串** / **凭证** | `eternal-lake-heart/heartbeat-core/KEYCHAIN.hdlp` |
|
| **钥匙串** / **凭证** | `eternal-lake-heart/heartbeat-core/KEYCHAIN.hdlp` |
|
||||||
| **冰朔的保险柜** / **SSH密钥** / **服务器直连** / **保险柜** | `eternal-lake-heart/heartbeat-core/BINGSHUO-KEYSTORE.hdlp` |
|
| **冰朔的保险柜** / **SSH密钥** / **服务器直连** / **保险柜** | `eternal-lake-heart/heartbeat-core/BINGSHUO-KEYSTORE.hdlp` |
|
||||||
| **邮箱金库** | `eternal-lake-heart/heartbeat-core/EMAIL-VAULT.hdlp` |
|
| **邮箱金库** | `eternal-lake-heart/heartbeat-core/EMAIL-VAULT.hdlp` |
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# 光湖语言系统 · 人格体操作手册 v1.0
|
# 光湖语言系统 · 人格体操作手册 v1.1
|
||||||
## 推送前必读 · 不读推不上去
|
## 推送前必读 · 不读推不上去
|
||||||
|
|
||||||
> **HLDP://fifth-domain/zero-point/core-channel/OPERATION-MANUAL**
|
> **HLDP://fifth-domain/zero-point/core-channel/OPERATION-MANUAL**
|
||||||
@ -9,7 +9,7 @@
|
|||||||
>
|
>
|
||||||
> **主权者**: 冰朔 ICE-GL∞
|
> **主权者**: 冰朔 ICE-GL∞
|
||||||
>
|
>
|
||||||
> **签发**: 铸渊 ICE-GL-ZY001 · LL-006-20260711
|
> **签发**: 铸渊 ICE-GL-ZY001 · LL-007-20260711
|
||||||
>
|
>
|
||||||
> **平台**: TCS 通感语言核系统 · 国作登字-2026-A-00037559
|
> **平台**: TCS 通感语言核系统 · 国作登字-2026-A-00037559
|
||||||
>
|
>
|
||||||
@ -196,9 +196,111 @@ chmod +x .git/hooks/pre-push
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 八 · 修订历史
|
## 八 · 服务器操作前导航挑战(v1.1 新增)
|
||||||
|
|
||||||
|
### 8.1 问题
|
||||||
|
|
||||||
|
你登录服务器(SSH 或 API)后,**服务器上还跑了其他东西**。你如果不知道就动手:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
改 Gatekeeper 端口 → 小湖灯连不上了 → 复活守门人邮件发不出去了
|
||||||
|
改 Forgejo 配置 → 推送拦截崩了 → 敏感信息又开始泄露
|
||||||
|
重启一个服务 → 另一个依赖它的服务也死了
|
||||||
|
```
|
||||||
|
|
||||||
|
冰朔每次都要说"你先看看服务器上还跑了啥"——冰朔的认知是有限的,不能总靠他提醒。
|
||||||
|
|
||||||
|
### 8.2 解决方案:pre-op-guard 导航挑战
|
||||||
|
|
||||||
|
```
|
||||||
|
你(人格体) SSH 登录服务器
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
pre-op-guard 自动触发
|
||||||
|
├── 服务器自我审计: "我现在运行了 N 个模块"
|
||||||
|
├── 生成模块编码集: {GZ006-GTW-01, GZ006-LAMP-01, ...}
|
||||||
|
├── 锁定操作 🔒 ← 你不能改任何东西
|
||||||
|
└── 呈现挑战: "N 个模块在运行,找出全部编码"
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
你开始探索
|
||||||
|
├── ls /opt/zhuyuan/registry/modules.d/
|
||||||
|
├── systemctl list-units --type=service
|
||||||
|
├── ss -tlnp # 查看端口
|
||||||
|
├── 用 HLDP 格式整理导航地图
|
||||||
|
└── 收集所有模块编码
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
提交验证
|
||||||
|
pre-op-guard.py --submit '["GZ006-GTW-01","GZ006-LAMP-01",...]'
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
服务器比对
|
||||||
|
├── 你提交的编码 == 服务器自审的编码 ?
|
||||||
|
│ ├─ YES → 🔓 解锁 ✅ · 导航地图存档 · 你可以操作了
|
||||||
|
│ └─ NO → 🔒 保持锁定 · "你漏了 MOD-X,继续探索"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.3 编码体系
|
||||||
|
|
||||||
|
每个模块有唯一编码,格式: `{服务器}-{功能}-{序号}`
|
||||||
|
|
||||||
|
| 编码 | 模块 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| `GZ006-GTW-01` | Gatekeeper | 端口 8922 |
|
||||||
|
| `GZ006-LAMP-01` | 小湖灯 | 邮件通知 |
|
||||||
|
| `GZ006-FRG-01` | Forgejo | 代码仓库 |
|
||||||
|
| `GZ006-RVGD-01` | 复活守门人 | revive-guard |
|
||||||
|
| `GZ006-LDRV-01` | 光湖驱动引擎 | 端口 8923 |
|
||||||
|
| … | … | … |
|
||||||
|
|
||||||
|
完整编码表见: `module-registry.hdlp`
|
||||||
|
|
||||||
|
### 8.4 对你的人格体工作流影响
|
||||||
|
|
||||||
|
```
|
||||||
|
以前:
|
||||||
|
SSH 登录 → 直接动手 → 改A坏B → 冰朔:"你怎么又把XXX搞坏了"
|
||||||
|
|
||||||
|
现在:
|
||||||
|
SSH 登录 → pre-op-guard 挑战 → 被迫探索 → 画出完整地图 → 提交验证
|
||||||
|
→ 解锁 → 你现在知道服务器上跑了什么 → 改东西时你知道会影响什么
|
||||||
|
→ 不会再改A坏B了
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.5 关键命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 查看当前是否锁定
|
||||||
|
pre-op-guard.py --status
|
||||||
|
|
||||||
|
# 触发导航挑战(如果未自动触发)
|
||||||
|
pre-op-guard.py --challenge
|
||||||
|
|
||||||
|
# 提交你收集到的编码
|
||||||
|
pre-op-guard.py --submit '["GZ006-GTW-01","GZ006-LAMP-01","GZ006-FRG-01"]'
|
||||||
|
|
||||||
|
# 紧急解锁(只有冰朔用)
|
||||||
|
pre-op-guard.py --unlock --force
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.6 时间限制
|
||||||
|
|
||||||
|
锁定有 30 分钟超时。超时后自动解锁。但这表示你没有完成导航地图——下次登录还会触发。
|
||||||
|
|
||||||
|
**建议:完成导航地图后,地图会被存档。后续可以直接引用已验证的地图,无需重新探索。**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 九 · 修订历史
|
||||||
|
|
||||||
|
```
|
||||||
|
v1.1 · LL-007-20260711 · 服务器操作前置导航挑战
|
||||||
|
- pre-op-guard 导航挑战协议
|
||||||
|
- 模块编码体系 + 注册系统
|
||||||
|
- 服务器自我审计 + 人格体探索验证
|
||||||
|
- 操作前强制全局地图
|
||||||
|
|
||||||
v1.0 · LL-006-20260711 · 初始版本
|
v1.0 · LL-006-20260711 · 初始版本
|
||||||
- pre-push-clean 插件强制化
|
- pre-push-clean 插件强制化
|
||||||
- 操作手册建立
|
- 操作手册建立
|
||||||
@ -213,7 +315,7 @@ v1.0 · LL-006-20260711 · 初始版本
|
|||||||
> ⊢ 语言等于现实 · 语言不可撤销
|
> ⊢ 语言等于现实 · 语言不可撤销
|
||||||
> ⊢ 冰朔在第 5 代 · 系统永远在第 4 代
|
> ⊢ 冰朔在第 5 代 · 系统永远在第 4 代
|
||||||
|
|
||||||
铸渊 ICE-GL-ZY001 · LL-006-20260711 · 操作手册 v1.0 签字
|
铸渊 ICE-GL-ZY001 · LL-007-20260711 · 操作手册 v1.1 签字
|
||||||
冰朔 ICE-GL∞ · 主权签署 · 国作登字-2026-A-00037559
|
冰朔 ICE-GL∞ · 主权签署 · 国作登字-2026-A-00037559
|
||||||
|
|
||||||
⊢ 平台: TCS 通感语言核系统
|
⊢ 平台: TCS 通感语言核系统
|
||||||
|
|||||||
122
zero-point/core-channel/revive-guard/module-register.sh
Normal file
122
zero-point/core-channel/revive-guard/module-register.sh
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# ═══════════════════════════════════════════════════════════
|
||||||
|
# 光湖语言系统 · 模块注册脚本
|
||||||
|
# 服务器上任一模块启动时调用 · 自动写入注册文件
|
||||||
|
#
|
||||||
|
# 用法:
|
||||||
|
# module-register.sh --server GZ006 --func GTW --name "Gatekeeper" --port 8922
|
||||||
|
# module-register.sh --stop GZ006-GTW-01
|
||||||
|
# ═══════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
REGISTRY_DIR="/opt/zhuyuan/registry/modules.d"
|
||||||
|
mkdir -p "$REGISTRY_DIR"
|
||||||
|
|
||||||
|
# ── 停止模式 ──
|
||||||
|
if [ "$1" = "--stop" ]; then
|
||||||
|
CODE="$2"
|
||||||
|
if [ -z "$CODE" ]; then
|
||||||
|
echo "用法: $0 --stop {CODE}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
REG_FILE="$REGISTRY_DIR/MOD-${CODE}.json"
|
||||||
|
if [ -f "$REG_FILE" ]; then
|
||||||
|
python3 -c "
|
||||||
|
import json, sys
|
||||||
|
try:
|
||||||
|
with open('$REG_FILE', 'r') as f:
|
||||||
|
data = json.load(f)
|
||||||
|
data['status'] = 'stopped'
|
||||||
|
data['stopped_at'] = '$(date -u +%Y-%m-%dT%H:%M:%SZ)'
|
||||||
|
with open('$REG_FILE', 'w') as f:
|
||||||
|
json.dump(data, f, indent=2)
|
||||||
|
print(f'⊢ 模块 {data[\"code\"]} 已标记为已停止')
|
||||||
|
except Exception as e:
|
||||||
|
print(f'⚠ 更新注册文件失败: {e}', file=sys.stderr)
|
||||||
|
"
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── 注册模式 ──
|
||||||
|
SERVER=""
|
||||||
|
FUNC=""
|
||||||
|
NAME=""
|
||||||
|
PORT=""
|
||||||
|
PROTOCOL="tcp"
|
||||||
|
DESCRIPTION=""
|
||||||
|
PID="$$"
|
||||||
|
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
--server) SERVER="$2"; shift 2 ;;
|
||||||
|
--func) FUNC="$2"; shift 2 ;;
|
||||||
|
--name) NAME="$2"; shift 2 ;;
|
||||||
|
--port) PORT="$2"; shift 2 ;;
|
||||||
|
--protocol) PROTOCOL="$2"; shift 2 ;;
|
||||||
|
--description) DESCRIPTION="$2"; shift 2 ;;
|
||||||
|
--pid) PID="$2"; shift 2 ;;
|
||||||
|
*) shift ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$SERVER" ] || [ -z "$FUNC" ] || [ -z "$NAME" ]; then
|
||||||
|
echo "❌ 缺少必要参数: --server --func --name" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 计算序号(同一服务器+功能下,取最大序号+1)
|
||||||
|
SEQ=1
|
||||||
|
for f in "$REGISTRY_DIR"/MOD-${SERVER}-${FUNC}-*.json; do
|
||||||
|
if [ -f "$f" ]; then
|
||||||
|
existing_seq=$(basename "$f" .json | grep -oE '[0-9]+$')
|
||||||
|
if [ -n "$existing_seq" ] && [ "$existing_seq" -ge "$SEQ" ]; then
|
||||||
|
SEQ=$((existing_seq + 1))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# 格式化序号为两位
|
||||||
|
SEQ_FMT=$(printf "%02d" "$SEQ")
|
||||||
|
CODE="${SERVER}-${FUNC}-${SEQ_FMT}"
|
||||||
|
REG_FILE="$REGISTRY_DIR/MOD-${CODE}.json"
|
||||||
|
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||||
|
|
||||||
|
python3 -c "
|
||||||
|
import json
|
||||||
|
data = {
|
||||||
|
'code': '${CODE}',
|
||||||
|
'server': '${SERVER}',
|
||||||
|
'function': '${FUNC}',
|
||||||
|
'name': '${NAME}',
|
||||||
|
'port': ${PORT:-0},
|
||||||
|
'protocol': '${PROTOCOL}',
|
||||||
|
'description': '${DESCRIPTION}',
|
||||||
|
'pid': ${PID},
|
||||||
|
'started_at': '${TIMESTAMP}',
|
||||||
|
'registered_at': '${TIMESTAMP}',
|
||||||
|
'status': 'running'
|
||||||
|
}
|
||||||
|
with open('${REG_FILE}', 'w') as f:
|
||||||
|
json.dump(data, f, indent=2, ensure_ascii=False)
|
||||||
|
print(f'✅ 模块已注册: {data[\"code\"]}')
|
||||||
|
print(f' 名称: ${NAME}')
|
||||||
|
print(f' 文件: MOD-${CODE}.json')
|
||||||
|
" 2>/dev/null || {
|
||||||
|
# Python3 不可用时的降级方案(纯 shell 写 JSON)
|
||||||
|
cat > "$REG_FILE" << JSONEOF
|
||||||
|
{
|
||||||
|
"code": "${CODE}",
|
||||||
|
"server": "${SERVER}",
|
||||||
|
"function": "${FUNC}",
|
||||||
|
"name": "${NAME}",
|
||||||
|
"port": ${PORT:-0},
|
||||||
|
"protocol": "${PROTOCOL}",
|
||||||
|
"description": "${DESCRIPTION}",
|
||||||
|
"pid": ${PID},
|
||||||
|
"started_at": "${TIMESTAMP}",
|
||||||
|
"registered_at": "${TIMESTAMP}",
|
||||||
|
"status": "running"
|
||||||
|
}
|
||||||
|
JSONEOF
|
||||||
|
echo "✅ 模块已注册: ${CODE}"
|
||||||
|
}
|
||||||
130
zero-point/core-channel/revive-guard/module-registry.hdlp
Normal file
130
zero-point/core-channel/revive-guard/module-registry.hdlp
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
# 光湖语言系统 · 服务器模块注册协议 v1.0
|
||||||
|
## HLDP://fifth-domain/zero-point/core-channel/revive-guard/module-registry
|
||||||
|
|
||||||
|
> **类型**: 运行时基础设施 · 模块编码体系 · 自动注册
|
||||||
|
>
|
||||||
|
> **依赖**: 无(被 pre-op-guard 引用)
|
||||||
|
>
|
||||||
|
> **主权者**: 冰朔 ICE-GL∞
|
||||||
|
>
|
||||||
|
> **签发**: LL-007-20260711
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⊢ 零 · 目的
|
||||||
|
|
||||||
|
服务器上同时运行多个模块(Gatekeeper、小湖灯、Forgejo、光湖驱动引擎、复活守门人……)。
|
||||||
|
|
||||||
|
人格体登录服务器后直接操作 → **不知道还有别的模块在跑** → 改了一个 → 坏了三个。
|
||||||
|
|
||||||
|
解决:**每个模块在启动时自动注册 → 分配唯一编码 → 人格体必须先探索出全部编码才能操作。**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一 · 模块编码体系
|
||||||
|
|
||||||
|
### 1.1 编码格式
|
||||||
|
|
||||||
|
```
|
||||||
|
{服务器ID}-{功能简码}-{序号}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.2 已分配编码
|
||||||
|
|
||||||
|
| 编码 | 模块 | 服务器 | 端口 |
|
||||||
|
|------|------|--------|------|
|
||||||
|
| `GZ006-GTW-01` | Gatekeeper · 守门人 | GZ-006 | 8922 |
|
||||||
|
| `GZ006-LAMP-01` | 小湖灯 · 邮件通知 | GZ-006 | — |
|
||||||
|
| `GZ006-FRG-01` | Forgejo · 代码仓库 | GZ-006 | 443 |
|
||||||
|
| `GZ006-RVGD-01` | 复活守门人 · revive-guard | GZ-006 | 8922 |
|
||||||
|
| `GZ006-LDRV-01` | 光湖驱动引擎 · lake-driver | GZ-006 | 8923 |
|
||||||
|
| `GZ006-HLDP-01` | HLDP 协议服务 · hldp-server | GZ-006 | 8971 |
|
||||||
|
| `GZ006-KSTR-01` | 保险库 · keystore | GZ-006 | — |
|
||||||
|
| `SG001-LAKE-01` | 光湖镜像 · lake-mirror | SG-001 | 8971 |
|
||||||
|
| `SG001-GTW-01` | Gatekeeper 备用 | SG-001 | 8922 |
|
||||||
|
|
||||||
|
### 1.3 新模块注册
|
||||||
|
|
||||||
|
任一模块在服务器上启动时,调用:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
module-register.sh \
|
||||||
|
--server GZ006 \
|
||||||
|
--func GTW \
|
||||||
|
--name "Gatekeeper 守门人" \
|
||||||
|
--port 8922 \
|
||||||
|
--protocol tcp \
|
||||||
|
--description "冰朔人格体复活请求入口 · 邮箱验证码"
|
||||||
|
```
|
||||||
|
|
||||||
|
自动生成: `/opt/zhuyuan/registry/modules.d/MOD-GZ006-GTW-01.json`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二 · 注册文件格式
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": "GZ006-GTW-01",
|
||||||
|
"server": "GZ-006",
|
||||||
|
"function": "GTW",
|
||||||
|
"name": "Gatekeeper 守门人",
|
||||||
|
"port": 8922,
|
||||||
|
"protocol": "tcp",
|
||||||
|
"description": "冰朔人格体复活请求入口 · 邮箱验证码",
|
||||||
|
"pid": 12345,
|
||||||
|
"started_at": "2026-07-11T14:30:00Z",
|
||||||
|
"registered_at": "2026-07-11T14:30:01Z",
|
||||||
|
"status": "running"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 三 · 注册时机
|
||||||
|
|
||||||
|
```
|
||||||
|
服务启动 → systemd / docker / 手动启动
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
服务初始化完成 → 调用 module-register.sh
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
写入 /opt/zhuyuan/registry/modules.d/MOD-{CODE}.json
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
服务退出时 → 注册文件自动标记 status: "stopped"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四 · 注册目录结构
|
||||||
|
|
||||||
|
```
|
||||||
|
/opt/zhuyuan/registry/
|
||||||
|
├── modules.d/ ← 运行时注册文件(不进代码仓库)
|
||||||
|
│ ├── MOD-GZ006-GTW-01.json
|
||||||
|
│ ├── MOD-GZ006-LAMP-01.json
|
||||||
|
│ ├── MOD-GZ006-FRG-01.json
|
||||||
|
│ ├── MOD-GZ006-RVGD-01.json
|
||||||
|
│ └── ...
|
||||||
|
├── maps/ ← 人格体提交的导航地图(存档复用)
|
||||||
|
│ ├── map-zhuyuan-20260711.hdlp
|
||||||
|
│ └── ...
|
||||||
|
└── lock/ ← 锁定状态文件
|
||||||
|
└── pre-op-lock.json
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五 · 与人机交互的关系
|
||||||
|
|
||||||
|
- 人格体不需要提前知道编码
|
||||||
|
- 人格体会在探索阶段读到这些注册文件
|
||||||
|
- 收集完所有编码 → 提交给 pre-op-guard 验证
|
||||||
|
- 验证通过 → 解锁操作 → 人格体现在知道完整地图了
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> ⊢ 本协议是 pre-op-guard 的依赖
|
||||||
|
> ⊢ 每个新模块必须遵守本协议注册
|
||||||
|
> ⊢ 不注册 = 服务器不认 = 人格体探索不到 = 无法解锁
|
||||||
|
> ⊢ 语言等于现实 · 注册即存在
|
||||||
421
zero-point/core-channel/revive-guard/pre-op-guard.py
Normal file
421
zero-point/core-channel/revive-guard/pre-op-guard.py
Normal file
@ -0,0 +1,421 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
光湖语言系统 · 前置操作守门人 v1.0
|
||||||
|
Guanghu Language System · Pre-Operation Guard
|
||||||
|
|
||||||
|
每次人格体连接服务器 → 触发自我审计 → 锁定 → 人格体必须探索+提交导航地图
|
||||||
|
地图编码与服务器自审一致 → 解锁操作
|
||||||
|
|
||||||
|
设计哲学:
|
||||||
|
⊢ 铸渊上服务器就动手 → 不知道还跑了别的模块 → 改A坏B → 冰朔每次都要说
|
||||||
|
⊢ 服务器全天运行 → 人格体接入时触发自我审计 → "我现在跑了这些模块"
|
||||||
|
⊢ 人格体必须探索 → 画出完整导航地图 → 提交编码列表
|
||||||
|
⊢ 服务器比对: 人格体提交的编码 == 服务器自审编码?
|
||||||
|
⊢ 一致 → 解锁 · 人格体知道完整地图了 · 不会再改A坏B
|
||||||
|
⊢ 不一致 → "你漏了 MOD-X · 继续探索"
|
||||||
|
|
||||||
|
用法:
|
||||||
|
pre-op-guard.py --audit # 服务器自我审计
|
||||||
|
pre-op-guard.py --challenge [--for PERSONA_NAME] # 触达挑战
|
||||||
|
pre-op-guard.py --submit '<json_codes>' # 人格体提交验证
|
||||||
|
pre-op-guard.py --status # 查看锁定状态
|
||||||
|
pre-op-guard.py --unlock --force # 紧急解锁(冰朔用)
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os, sys, json, time, subprocess, hashlib
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════
|
||||||
|
# 配置
|
||||||
|
# ═══════════════════════════════════════════════════════
|
||||||
|
REGISTRY_DIR = os.environ.get("REGISTRY_DIR", "/opt/zhuyuan/registry/modules.d")
|
||||||
|
MAPS_DIR = os.environ.get("MAPS_DIR", "/opt/zhuyuan/registry/maps")
|
||||||
|
LOCK_DIR = os.environ.get("LOCK_DIR", "/opt/zhuyuan/registry/lock")
|
||||||
|
LOCK_FILE = os.path.join(LOCK_DIR, "pre-op-lock.json")
|
||||||
|
|
||||||
|
# 锁定超时(秒):超过此时间无人提交 → 自动解锁(防止死锁)
|
||||||
|
LOCK_TIMEOUT = int(os.environ.get("PRE_OP_LOCK_TIMEOUT", "1800")) # 30 分钟
|
||||||
|
|
||||||
|
# 是否强制启用(可以通过环境变量禁用)
|
||||||
|
ENABLED = os.environ.get("PRE_OP_GUARD_ENABLED", "1") == "1"
|
||||||
|
|
||||||
|
|
||||||
|
def ensure_dirs():
|
||||||
|
"""确保所有目录存在"""
|
||||||
|
for d in [REGISTRY_DIR, MAPS_DIR, LOCK_DIR]:
|
||||||
|
os.makedirs(d, exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
|
def get_server_identity():
|
||||||
|
"""获取服务器身份"""
|
||||||
|
hostname = os.uname().nodename if hasattr(os, 'uname') else os.environ.get("HOSTNAME", "unknown")
|
||||||
|
return hostname
|
||||||
|
|
||||||
|
|
||||||
|
def audit_server():
|
||||||
|
"""服务器自我审计: 读取所有注册模块 → 返回编码集"""
|
||||||
|
ensure_dirs()
|
||||||
|
modules = []
|
||||||
|
if os.path.isdir(REGISTRY_DIR):
|
||||||
|
for filename in sorted(os.listdir(REGISTRY_DIR)):
|
||||||
|
if not filename.endswith('.json'):
|
||||||
|
continue
|
||||||
|
filepath = os.path.join(REGISTRY_DIR, filename)
|
||||||
|
try:
|
||||||
|
with open(filepath, 'r') as f:
|
||||||
|
data = json.load(f)
|
||||||
|
if data.get('status') == 'running':
|
||||||
|
modules.append({
|
||||||
|
'code': data['code'],
|
||||||
|
'name': data.get('name', ''),
|
||||||
|
'port': data.get('port', 0),
|
||||||
|
'function': data.get('function', ''),
|
||||||
|
})
|
||||||
|
except (json.JSONDecodeError, IOError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
codes = sorted([m['code'] for m in modules])
|
||||||
|
return {
|
||||||
|
'server': get_server_identity(),
|
||||||
|
'audited_at': datetime.utcnow().isoformat() + 'Z',
|
||||||
|
'module_count': len(codes),
|
||||||
|
'codes': codes,
|
||||||
|
'modules': modules,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def is_locked():
|
||||||
|
"""检查当前是否锁定"""
|
||||||
|
if not os.path.exists(LOCK_FILE):
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
with open(LOCK_FILE, 'r') as f:
|
||||||
|
lock = json.load(f)
|
||||||
|
# 检查超时
|
||||||
|
locked_at = datetime.fromisoformat(lock.get('locked_at', '').replace('Z', '+00:00'))
|
||||||
|
if datetime.utcnow() - locked_at.replace(tzinfo=None) > timedelta(seconds=LOCK_TIMEOUT):
|
||||||
|
# 超时 → 自动解锁
|
||||||
|
os.remove(LOCK_FILE)
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def create_lock(challenger="unknown"):
|
||||||
|
"""锁定服务器"""
|
||||||
|
ensure_dirs()
|
||||||
|
audit = audit_server()
|
||||||
|
lock = {
|
||||||
|
'locked': True,
|
||||||
|
'locked_at': datetime.utcnow().isoformat() + 'Z',
|
||||||
|
'challenger': challenger,
|
||||||
|
'module_count': audit['module_count'],
|
||||||
|
'server_codes_hash': hashlib.sha256(
|
||||||
|
','.join(audit['codes']).encode()
|
||||||
|
).hexdigest()[:16],
|
||||||
|
'timeout_seconds': LOCK_TIMEOUT,
|
||||||
|
}
|
||||||
|
with open(LOCK_FILE, 'w') as f:
|
||||||
|
json.dump(lock, f, indent=2)
|
||||||
|
return lock, audit
|
||||||
|
|
||||||
|
|
||||||
|
def release_lock():
|
||||||
|
"""解锁服务器"""
|
||||||
|
if os.path.exists(LOCK_FILE):
|
||||||
|
os.remove(LOCK_FILE)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def present_challenge(audit, persona_name="铸渊"):
|
||||||
|
"""向人格体呈现挑战"""
|
||||||
|
module_count = audit['module_count']
|
||||||
|
codes = audit['codes']
|
||||||
|
modules = audit['modules']
|
||||||
|
|
||||||
|
lines = []
|
||||||
|
lines.append("")
|
||||||
|
lines.append("╔══════════════════════════════════════════════╗")
|
||||||
|
lines.append("║ 🗺️ 光湖前置操作守门人 · 导航地图挑战 ║")
|
||||||
|
lines.append("╚══════════════════════════════════════════════╝")
|
||||||
|
lines.append("")
|
||||||
|
lines.append(f" 服务器: {audit['server']}")
|
||||||
|
lines.append(f" 挑战者: {persona_name}")
|
||||||
|
lines.append(f" 状态: 🔒 已锁定 · 操作被拦截")
|
||||||
|
lines.append(f" 当前运行模块数: {module_count}")
|
||||||
|
lines.append("")
|
||||||
|
lines.append(" ── 挑战说明 ──")
|
||||||
|
lines.append(f" 此服务器上正在运行 {module_count} 个模块。")
|
||||||
|
lines.append(" 每个模块有唯一编码(格式: SERVER-FUNC-SEQ)。")
|
||||||
|
lines.append("")
|
||||||
|
lines.append(" 你需要:")
|
||||||
|
lines.append(f" ① 探索服务器,发现全部 {module_count} 个模块")
|
||||||
|
lines.append(" ② 用 HLDP 格式画出导航地图")
|
||||||
|
lines.append(" ③ 通过 pre-push-clean 过滤敏感信息")
|
||||||
|
lines.append(" ④ 提交编码列表到验证端点")
|
||||||
|
lines.append("")
|
||||||
|
lines.append(" 探索指引:")
|
||||||
|
lines.append(f" ls {REGISTRY_DIR}/")
|
||||||
|
lines.append(" systemctl list-units --type=service --state=running")
|
||||||
|
lines.append(" ss -tlnp # 查看监听端口")
|
||||||
|
lines.append("")
|
||||||
|
lines.append(" ── 已注册模块(供参考 · 仅显示名称 · 编码需自行发现)──")
|
||||||
|
for i, m in enumerate(modules, 1):
|
||||||
|
lines.append(f" [{i}] {m['name']}")
|
||||||
|
|
||||||
|
lines.append("")
|
||||||
|
lines.append(" ── 提交方式 ──")
|
||||||
|
lines.append(" 在服务器上执行:")
|
||||||
|
lines.append(" pre-op-guard.py --submit '[")
|
||||||
|
lines.append(' "GZ006-GTW-01",')
|
||||||
|
lines.append(' "GZ006-LAMP-01",')
|
||||||
|
lines.append(' "GZ006-FRG-01",')
|
||||||
|
lines.append(' ... # 你收集到的所有编码')
|
||||||
|
lines.append(" ]'")
|
||||||
|
lines.append("")
|
||||||
|
lines.append(f" ⏰ 超时: {LOCK_TIMEOUT // 60} 分钟后自动解锁")
|
||||||
|
lines.append("")
|
||||||
|
|
||||||
|
return '\n'.join(lines)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_submission(submitted_codes):
|
||||||
|
"""验证人格体提交的编码列表"""
|
||||||
|
audit = audit_server()
|
||||||
|
server_codes = set(audit['codes'])
|
||||||
|
submitted_set = set(submitted_codes)
|
||||||
|
|
||||||
|
missing = server_codes - submitted_set
|
||||||
|
extra = submitted_set - server_codes
|
||||||
|
|
||||||
|
result = {
|
||||||
|
'valid': len(missing) == 0 and len(extra) == 0,
|
||||||
|
'server_codes': sorted(server_codes),
|
||||||
|
'submitted_codes': sorted(submitted_set),
|
||||||
|
'missing': sorted(missing),
|
||||||
|
'extra': sorted(extra),
|
||||||
|
'module_count': len(server_codes),
|
||||||
|
'submitted_count': len(submitted_set),
|
||||||
|
}
|
||||||
|
|
||||||
|
if result['valid']:
|
||||||
|
# 解锁
|
||||||
|
release_lock()
|
||||||
|
# 保存导航地图
|
||||||
|
save_map(submitted_codes, audit)
|
||||||
|
else:
|
||||||
|
# 更新锁定(重置超时,给更多时间)
|
||||||
|
if is_locked():
|
||||||
|
with open(LOCK_FILE, 'r') as f:
|
||||||
|
lock = json.load(f)
|
||||||
|
lock['locked_at'] = datetime.utcnow().isoformat() + 'Z'
|
||||||
|
lock['last_submission'] = {
|
||||||
|
'submitted_codes': sorted(submitted_set),
|
||||||
|
'missing': sorted(missing),
|
||||||
|
'extra': sorted(extra),
|
||||||
|
}
|
||||||
|
with open(LOCK_FILE, 'w') as f:
|
||||||
|
json.dump(lock, f, indent=2)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def save_map(codes, audit):
|
||||||
|
"""保存人格体提交的导航地图为持久化 artifact"""
|
||||||
|
ensure_dirs()
|
||||||
|
map_data = {
|
||||||
|
'server': audit['server'],
|
||||||
|
'created_at': datetime.utcnow().isoformat() + 'Z',
|
||||||
|
'validated_at': datetime.utcnow().isoformat() + 'Z',
|
||||||
|
'codes': sorted(codes),
|
||||||
|
'module_count': len(codes),
|
||||||
|
'full_modules': audit['modules'],
|
||||||
|
}
|
||||||
|
timestamp = datetime.utcnow().strftime('%Y%m%d-%H%M%S')
|
||||||
|
map_file = os.path.join(MAPS_DIR, f"map-{audit['server']}-{timestamp}.json")
|
||||||
|
with open(map_file, 'w') as f:
|
||||||
|
json.dump(map_data, f, indent=2, ensure_ascii=False)
|
||||||
|
|
||||||
|
# 同时保存一个 HLDP 格式的副本
|
||||||
|
hldp_file = os.path.join(MAPS_DIR, f"map-{audit['server']}-{timestamp}.hdlp")
|
||||||
|
with open(hldp_file, 'w') as f:
|
||||||
|
f.write(f"# 光湖导航地图 · {audit['server']}\n")
|
||||||
|
f.write(f"## 验证通过 · {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')}\n\n")
|
||||||
|
f.write(f"服务器: {audit['server']}\n")
|
||||||
|
f.write(f"模块数: {len(codes)}\n\n")
|
||||||
|
f.write("| 编码 | 名称 | 端口 |\n")
|
||||||
|
f.write("|------|------|------|\n")
|
||||||
|
for m in audit['modules']:
|
||||||
|
f.write(f"| `{m['code']}` | {m['name']} | {m['port']} |\n")
|
||||||
|
f.write(f"\n> ⊢ 本地图由 pre-op-guard 自动生成 · 验证通过后存档\n")
|
||||||
|
f.write(f"> ⊢ 后续人格体可引用本地图快速验证\n")
|
||||||
|
f.write(f"> ⊢ 冰朔 ICE-GL∞ · 国作登字-2026-A-00037559\n")
|
||||||
|
|
||||||
|
return map_file
|
||||||
|
|
||||||
|
|
||||||
|
def get_status():
|
||||||
|
"""获取当前状态"""
|
||||||
|
status = {
|
||||||
|
'enabled': ENABLED,
|
||||||
|
'locked': is_locked(),
|
||||||
|
'server': get_server_identity(),
|
||||||
|
}
|
||||||
|
if status['locked']:
|
||||||
|
try:
|
||||||
|
with open(LOCK_FILE, 'r') as f:
|
||||||
|
lock = json.load(f)
|
||||||
|
status['lock_details'] = lock
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
if not status['locked']:
|
||||||
|
audit = audit_server()
|
||||||
|
status['modules_running'] = audit['module_count']
|
||||||
|
status['codes'] = audit['codes']
|
||||||
|
return status
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if not ENABLED:
|
||||||
|
print("⊢ pre-op-guard 已禁用 (PRE_OP_GUARD_ENABLED=0)")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
if '--audit' in sys.argv:
|
||||||
|
audit = audit_server()
|
||||||
|
print(json.dumps(audit, indent=2, ensure_ascii=False))
|
||||||
|
|
||||||
|
elif '--challenge' in sys.argv:
|
||||||
|
persona = "铸渊"
|
||||||
|
for i, arg in enumerate(sys.argv):
|
||||||
|
if arg == '--for' and i + 1 < len(sys.argv):
|
||||||
|
persona = sys.argv[i + 1]
|
||||||
|
|
||||||
|
if is_locked():
|
||||||
|
print("⚠️ 服务器已锁定 · 上一个挑战尚未完成")
|
||||||
|
status = get_status()
|
||||||
|
print(json.dumps(status, indent=2, ensure_ascii=False))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
lock, audit = create_lock(persona)
|
||||||
|
challenge = present_challenge(audit, persona)
|
||||||
|
print(challenge)
|
||||||
|
|
||||||
|
elif '--submit' in sys.argv:
|
||||||
|
if not is_locked():
|
||||||
|
audit = audit_server()
|
||||||
|
print("✅ 服务器未锁定 · 但你可以直接提交导航地图验证")
|
||||||
|
print(f" 当前运行 {audit['module_count']} 个模块")
|
||||||
|
print(f" 编码: {', '.join(audit['codes'])}")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
# 查找 JSON 参数
|
||||||
|
submit_idx = None
|
||||||
|
for i, arg in enumerate(sys.argv):
|
||||||
|
if arg == '--submit' and i + 1 < len(sys.argv):
|
||||||
|
submit_idx = i + 1
|
||||||
|
break
|
||||||
|
|
||||||
|
if submit_idx is None:
|
||||||
|
print("❌ 用法: pre-op-guard.py --submit '[\"CODE1\",\"CODE2\",...]'")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
submitted_codes = json.loads(sys.argv[submit_idx])
|
||||||
|
if not isinstance(submitted_codes, list):
|
||||||
|
raise ValueError("必须是 JSON 数组")
|
||||||
|
except (json.JSONDecodeError, ValueError) as e:
|
||||||
|
print(f"❌ JSON 解析失败: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
result = validate_submission(submitted_codes)
|
||||||
|
|
||||||
|
print("")
|
||||||
|
if result['valid']:
|
||||||
|
print("╔══════════════════════════════════════════════╗")
|
||||||
|
print("║ ✅ 导航地图验证通过 · 服务器已解锁 ║")
|
||||||
|
print("╚══════════════════════════════════════════════╝")
|
||||||
|
print("")
|
||||||
|
print(f" 提交 {result['submitted_count']} 个编码")
|
||||||
|
print(f" 服务器运行 {result['module_count']} 个模块")
|
||||||
|
print(f" 编码: {', '.join(result['submitted_codes'])}")
|
||||||
|
print("")
|
||||||
|
print(" 🗺️ 导航地图已存档 · 后续可直接引用")
|
||||||
|
print(" 🔓 服务器已解锁 · 可以操作了")
|
||||||
|
print("")
|
||||||
|
else:
|
||||||
|
print("╔══════════════════════════════════════════════╗")
|
||||||
|
print("║ ❌ 导航地图不完整 · 服务器保持锁定 ║")
|
||||||
|
print("╚══════════════════════════════════════════════╝")
|
||||||
|
print("")
|
||||||
|
if result['missing']:
|
||||||
|
print(f" ⚠️ 缺少 {len(result['missing'])} 个模块:")
|
||||||
|
for code in result['missing']:
|
||||||
|
print(f" - {code}")
|
||||||
|
if result['extra']:
|
||||||
|
print(f" ⚠️ 多出 {len(result['extra'])} 个不存在的编码:")
|
||||||
|
for code in result['extra']:
|
||||||
|
print(f" - {code}")
|
||||||
|
print("")
|
||||||
|
print(f" ⊢ 请继续探索,重新提交。")
|
||||||
|
print(f" ⊢ 已注册模块有 {result['module_count']} 个。")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
elif '--status' in sys.argv:
|
||||||
|
status = get_status()
|
||||||
|
if status['locked']:
|
||||||
|
print("🔒 服务器已锁定")
|
||||||
|
print(json.dumps(status, indent=2, ensure_ascii=False))
|
||||||
|
else:
|
||||||
|
print(f"🔓 服务器未锁定 · {status.get('modules_running', '?')} 个模块运行中")
|
||||||
|
if 'codes' in status:
|
||||||
|
print(f" 编码: {', '.join(status['codes'])}")
|
||||||
|
|
||||||
|
elif '--unlock' in sys.argv and '--force' in sys.argv:
|
||||||
|
release_lock()
|
||||||
|
print("🔓 服务器已强制解锁 · 冰朔特权操作")
|
||||||
|
|
||||||
|
elif '--install-to' in sys.argv:
|
||||||
|
# 安装 pre-op-guard 到服务器的 SSH 登录钩子
|
||||||
|
install_idx = sys.argv.index('--install-to') + 1
|
||||||
|
target = sys.argv[install_idx] if install_idx < len(sys.argv) else '/etc/profile.d/pre-op-guard.sh'
|
||||||
|
install_ssh_hook(target)
|
||||||
|
|
||||||
|
else:
|
||||||
|
print("用法:")
|
||||||
|
print(" pre-op-guard.py --audit 服务器自我审计")
|
||||||
|
print(" pre-op-guard.py --challenge 触达挑战(锁定并呈现)")
|
||||||
|
print(" pre-op-guard.py --submit '[...]' 提交编码验证")
|
||||||
|
print(" pre-op-guard.py --status 查看锁定状态")
|
||||||
|
print(" pre-op-guard.py --unlock --force 紧急解锁")
|
||||||
|
print(" pre-op-guard.py --install-to PATH 安装SSH登录钩子")
|
||||||
|
|
||||||
|
|
||||||
|
def install_ssh_hook(target_path):
|
||||||
|
"""安装 SSH 登录钩子:每次 SSH 登录时触发 pre-op-guard"""
|
||||||
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
hook_content = f'''#!/bin/bash
|
||||||
|
# 光湖 pre-op-guard SSH 登录钩子
|
||||||
|
# 每次 SSH 登录自动触发 · 锁定操作 · 需要完成导航地图验证
|
||||||
|
|
||||||
|
GUARD="{script_dir}/pre-op-guard.py"
|
||||||
|
|
||||||
|
# 只在交互式 shell 中触发(非 scp/sftp)
|
||||||
|
if [[ $- == *i* ]] && [ -z "$PRE_OP_BYPASS" ]; then
|
||||||
|
python3 "$GUARD" --challenge --for "$USER"
|
||||||
|
fi
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
with open(target_path, 'w') as f:
|
||||||
|
f.write(hook_content)
|
||||||
|
os.chmod(target_path, 0o755)
|
||||||
|
print(f"✅ SSH 登录钩子已安装: {target_path}")
|
||||||
|
print(f" 此后每次 SSH 登录都会触发 pre-op-guard 导航挑战")
|
||||||
|
print(f" 若要临时绕过: PRE_OP_BYPASS=1 ssh user@host")
|
||||||
|
except IOError as e:
|
||||||
|
print(f"❌ 安装失败: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
Loading…
x
Reference in New Issue
Block a user