v3.5:命主档案系统;技能介绍按场景触发;声明式偏离通道

- 新增 memory/ 命主档案:memory_save/memory_lookup 建档检索,
  反馈三态(已核实/已证伪/未核实),档案只存本机不进副本
- SKILL.md description 改写为按问题域与使用场景触发;
  输出契约补 R-禁-22 偏离须声明(编号+理由+书证)联动
- R-运-31 事类映射表改开放清单措辞
- 规则库 541→542 条(新增 R-禁-22),库版本 3.5
- 测试全套 69 项通过
This commit is contained in:
2026-10-09 21:01:55 +08:00
parent 618bf8dcab
commit 5889d7a150
11 changed files with 634 additions and 7 deletions
+81
View File
@@ -0,0 +1,81 @@
#!/usr/bin/env python3
"""命主档案检索 —— 按任意组合条件查 memory/archives/。
用法:
python memory_lookup.py [--name 张三] [--birth "1990-05-14 08:30"] \
[--place 四川省成都市] [--gender 男] [--pillars "丁亥 乙巳 庚子 辛巳"]
条件可任意组合(至少一项),全部命中才算匹配;比较大小写/空白容错。
输出:每份命中档案的路径与 frontmatter 摘要;无匹配输出「无档案」。
只读档案、不排盘,不经过软锁。档案规范见 memory/README.md。
退出码:0 检索完成(含无匹配);2 输入不可用;3 内部错误。
"""
import argparse
import sys
import traceback
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent))
import _memory_store as store
def main() -> int:
ap = argparse.ArgumentParser(
prog="memory_lookup.py",
description="命主档案检索:按姓名/出生时刻/出生地/性别/四柱任意组合查 memory/archives/",
)
ap.add_argument("--name", default=None, help="姓名")
ap.add_argument("--gender", default=None, choices=["男", "女"], help="性别")
ap.add_argument("--birth", default=None,
help='出生时刻(当地钟表时间),格式 "YYYY-MM-DD HH:MM"')
ap.add_argument("--place", default=None, help="出生地")
ap.add_argument("--pillars", default=None,
help='四柱干支,年月日时顺序,空格分隔,如 "丁亥 乙巳 庚子 辛巳"')
ap.add_argument("--memory-root", default=None,
help=f"档案根目录(默认技能根 memory/;亦可用环境变量 {store.ENV_VAR})")
a = ap.parse_args()
if all(v is None for v in (a.name, a.gender, a.birth, a.place, a.pillars)):
print("ERROR: 至少给一个检索条件(--name/--birth/--place/--gender/--pillars)。",
file=sys.stderr)
return 2
if a.pillars is not None and len(a.pillars.split()) != 4:
print("ERROR: --pillars 应为年月日时四组干支,如 \"丁亥 乙巳 庚子 辛巳\"。",
file=sys.stderr)
return 2
try:
root = store.resolve_root(a.memory_root, __file__)
hits = []
for path in store.iter_archives(root):
meta, _ = store.parse_frontmatter(path.read_text(encoding="utf-8"))
if not meta:
continue
if store.matches(meta, name=a.name, birth=a.birth, place=a.place,
gender=a.gender, pillars=a.pillars):
hits.append((path, meta))
if not hits:
print("无档案")
return 0
print(f"命中 {len(hits)} 份档案:\n")
for path, meta in hits:
print(path)
for k in store.FIELDS:
v = meta.get(k, "")
if isinstance(v, list):
v = " ".join(str(x) for x in v)
print(f" {k}: {v}")
print()
return 0
except Exception:
print("ERROR: 检索内部错误。", file=sys.stderr)
traceback.print_exc(file=sys.stderr)
return 3
if __name__ == "__main__":
raise SystemExit(main())