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:
@@ -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())
|
||||
Reference in New Issue
Block a user