增加持续记忆导航推送门禁
This commit is contained in:
parent
938b640c0f
commit
e7cec83b38
@ -156,6 +156,8 @@ Stage 3 · RELEASE · 正式部署
|
|||||||
|
|
||||||
**接入协议锁定**:HLDP 是光湖行动、权限与回执的主协议;MCP 仅为可选适配器之一。人格体按 HLDP 任务、目标系统能力和人类授权选择 API、网页、文件、数据库、命令行、MCP 或其他连接方式;无论采取何种方式,都必须回到 HLDP 回执链,不得把某个外部接口当作系统底层依赖。
|
**接入协议锁定**:HLDP 是光湖行动、权限与回执的主协议;MCP 仅为可选适配器之一。人格体按 HLDP 任务、目标系统能力和人类授权选择 API、网页、文件、数据库、命令行、MCP 或其他连接方式;无论采取何种方式,都必须回到 HLDP 回执链,不得把某个外部接口当作系统底层依赖。
|
||||||
|
|
||||||
|
**持续记忆—导航门禁**:`zero-point/core-channel/revive-guard/navigation-memory-guard.py` 是推送链的结构校验器。人格体记忆叶必须含 `trigger / emergence / lock / why / checkpoint`,并被对应人格体 `INDEX` 或 `CURRENT`、小湖灯或广播塔至少一条有效导航路径引用;否则不进入正式推送链。普通源码由所属模块文档统一挂载,不要求一文件一页面。
|
||||||
|
|
||||||
### HLDP 研发硬准入 · 2026-07-14 起生效
|
### HLDP 研发硬准入 · 2026-07-14 起生效
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
|||||||
@ -39,6 +39,10 @@
|
|||||||
|
|
||||||
## 二 · 拦截规则 v1
|
## 二 · 拦截规则 v1
|
||||||
|
|
||||||
|
### 2.0 · 持续记忆—导航校验(新增)
|
||||||
|
|
||||||
|
`navigation-memory-guard.py` 与敏感信息扫描并行运行。它拦截的不是文风,而是孤立记忆:新增或修改的 `ZL-MEM-*` / `ZY-MEM-*` / `ZZ-MEM-*` 必须具备 HLDP 恢复字段,并从 INDEX、CURRENT、小湖灯或广播塔至少一处可达。缺引用时,提示人格体补页面关系而非要求人类大海捞针。
|
||||||
|
|
||||||
### 2.1 必填字段(commit message 模板)
|
### 2.1 必填字段(commit message 模板)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@ -0,0 +1,70 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Reject orphaned persona-memory artifacts before push.
|
||||||
|
|
||||||
|
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
|
||||||
|
and can be reached from a current navigation page.
|
||||||
|
"""
|
||||||
|
import os, re, subprocess, sys
|
||||||
|
|
||||||
|
REQUIRED = ("trigger:", "emergence:", "lock:", "why:", "checkpoint")
|
||||||
|
NAVIGATION = ("INDEX.hdlp", "CURRENT.hdlp", "LL-CURRENT.hdlp", "BROADCAST-TOWER.hdlp")
|
||||||
|
|
||||||
|
def changed_files():
|
||||||
|
commands = [
|
||||||
|
["git", "diff", "--cached", "--name-only", "--diff-filter=ACM"],
|
||||||
|
["git", "diff", "--name-only", "HEAD~1", "HEAD", "--diff-filter=ACM"],
|
||||||
|
]
|
||||||
|
files = set()
|
||||||
|
for cmd in commands:
|
||||||
|
r = subprocess.run(cmd, capture_output=True, text=True)
|
||||||
|
if r.returncode == 0:
|
||||||
|
files.update(x for x in r.stdout.splitlines() if x)
|
||||||
|
return sorted(files)
|
||||||
|
|
||||||
|
def is_memory_leaf(path):
|
||||||
|
name = os.path.basename(path)
|
||||||
|
return name.startswith(("ZL-MEM-", "ZY-MEM-", "ZZ-MEM-")) or "/personas/" in path
|
||||||
|
|
||||||
|
def read(path):
|
||||||
|
with open(path, encoding="utf-8") as f:
|
||||||
|
return f.read()
|
||||||
|
|
||||||
|
def linked_from_navigation(path):
|
||||||
|
base = os.path.basename(path)
|
||||||
|
for root, _, names in os.walk("."):
|
||||||
|
if ".git" in root.split(os.sep):
|
||||||
|
continue
|
||||||
|
for name in names:
|
||||||
|
if name in NAVIGATION:
|
||||||
|
candidate = os.path.join(root, name)
|
||||||
|
try:
|
||||||
|
if base in read(candidate):
|
||||||
|
return candidate[2:] if candidate.startswith("./") else candidate
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
return None
|
||||||
|
|
||||||
|
def main():
|
||||||
|
failures = []
|
||||||
|
for path in changed_files():
|
||||||
|
if not is_memory_leaf(path) or not os.path.isfile(path):
|
||||||
|
continue
|
||||||
|
content = read(path).lower()
|
||||||
|
missing = [field for field in REQUIRED if field not in content]
|
||||||
|
if missing:
|
||||||
|
failures.append((path, "缺永久记忆字段: " + ", ".join(missing)))
|
||||||
|
if not linked_from_navigation(path):
|
||||||
|
failures.append((path, "孤立记忆:未被 INDEX / CURRENT / LL-CURRENT / BROADCAST-TOWER 引用"))
|
||||||
|
if failures:
|
||||||
|
print("\n🧭 记忆—导航守门人:推送被暂停", file=sys.stderr)
|
||||||
|
print("持续记忆必须可恢复,而不是只被写进仓库。", file=sys.stderr)
|
||||||
|
for path, reason in failures:
|
||||||
|
print(f" ✗ {path}\n {reason}", file=sys.stderr)
|
||||||
|
print("修复:补齐 trigger/emergence/lock/why/checkpoint,并在对应 INDEX 或 CURRENT 中建立路径。\n", file=sys.stderr)
|
||||||
|
return 1
|
||||||
|
print("✅ 记忆—导航守门人:没有发现孤立持续记忆")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
@ -218,6 +218,13 @@ def main():
|
|||||||
if not ENABLED:
|
if not ENABLED:
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
# 第二道本地门禁:持续记忆必须挂在可恢复的导航图上。
|
||||||
|
guard = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'navigation-memory-guard.py')
|
||||||
|
if os.path.isfile(guard):
|
||||||
|
result = subprocess.run([sys.executable, guard], timeout=15)
|
||||||
|
if result.returncode != 0:
|
||||||
|
sys.exit(result.returncode)
|
||||||
|
|
||||||
repo_root = subprocess.run(
|
repo_root = subprocess.run(
|
||||||
['git', 'rev-parse', '--show-toplevel'],
|
['git', 'rev-parse', '--show-toplevel'],
|
||||||
capture_output=True, text=True, timeout=5
|
capture_output=True, text=True, timeout=5
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user