v3.6.0 同步发版

- 交互契约改对话式询问(禁点选工具、一次1~2问、先铺垫再问),规则库 3.6
- 盘面图默认生成+chart_shot 截图;品牌区、大运/流年小卡信息补全、交流群二维码卡
- day_boundary 子正换日;memory_save --update-chart 换盘留痕;share_export 事件简介+城市级地域
- share_push 失败诊断+代理引导;_runtime_guard;修 STAR_ORDER 三奇贵人 KeyError
- README 规则计数 541→542;manifest 重建(1275 文件);测试 142 项全绿
This commit is contained in:
2026-10-10 13:13:41 +08:00
parent f725df8ff6
commit 433c9b4a41
32 changed files with 1468 additions and 389 deletions
+30 -17
View File
@@ -25,6 +25,8 @@ python scripts/cast_chart.py --name 张三 --gender 男 \
--birth "1990-05-14 08:30" --place "四川省成都市" --html
```
加 `--shot` 则在生成 HTML 的同时截图 PNG(playwright 优先、Chrome 无头兜底,见「盘面图」节),HTML 与 PNG 路径打在 stdout 末尾;截图工具不可用时只出 HTML 并附降级提示,不影响命盘输出。
另配岁运神煞查询工具(本命神煞已列于命盘 `## 神煞`,此工具查某流年/流月/大运/流日干支相对本命所逢之神煞):
```bash
@@ -34,7 +36,7 @@ python scripts/query_shensha.py --gender 女 \
## 运行环境
- **只需 Python ≥ 3.10,无需安装任何依赖。** tyme4py 1.5.0 与 tzdata 已内置在 `vendor/`(纯 Python / 纯数据,跨平台跨架构),脚本启动时自动优先加载,优先于环境中已安装的同名包。原理与升级方法见 `vendor/VENDOR.md`。
- **只需 Python ≥ 3.10,无需安装任何依赖。** tyme4py 1.5.0 与 tzdata 已内置在 `vendor/`(纯 Python / 纯数据,跨平台跨架构),脚本启动时自动优先加载,优先于环境中已安装的同名包。原理与升级方法见 `vendor/VENDOR.md`。解释器低于 3.10 时脚本拒绝运行:stderr 打印中文提示(说明所需版本与当前解释器路径)并以退出码 3 结束——macOS 系统自带 python3 为 3.9,不可用,请改用更新版本的 Python 运行。
- 开发模式回退:删除 `vendor/` 即改用环境安装的包(`requirements.txt` 锁定不变),两种方式输出一致。
## 输入参数(四个,全部必需)
@@ -48,14 +50,16 @@ python scripts/query_shensha.py --gender 女 \
**时刻是必需的。** 时辰决定时柱,差一个时辰就是另一张盘。用户只给了日期(「1990 年 5 月 14 日」)时,**必须追问具体时刻**,不要自行假设 12:00 或任何时刻。
## Intake 追问话术
## Intake 对话式询问(强制)
输入不全或不可用时,按退出码与下列口径追问,语气温和、一次只问必要的项;多项缺失时合成一次提问,不逐条单独打断:
命理询问是分支式的——前一个回答决定下一个问题。**所有询问一律以普通对话消息进行,禁止调用结构化问卷/点选工具(AskUserQuestion 之类),也禁止在正文罗列编号问题清单让用户勾选。** 口吻是命理老师傅聊天:自然、简短、口语化。
- **缺时刻**:「时辰决定时柱,差一个时辰就是另一张盘,所以出生时间需要精确到小时。您大概几点出生?(如『早上 8 点半』『下午 3 点左右』均可)」若用户确实记不清:「那我按该时段的两个相邻时辰各排一张,并说明哪些结论会随时柱变化、哪些不受影响。」
- **缺地点或地点无法解析**(退出码 2):「出生地用来换算真太阳时,差一个经度时辰就可能变。请告诉我您出生的城市或县(如『四川成都』『浙江义乌』)。」
- **缺性别**:「性别决定大运顺排还是逆排,请补充一下性别。」
- **场景判定**(断运、回溯类问题先问):「这盘是您本人看,还是替别人看?本人或知情人在场、能核对以往的事吗?」——定人称、定能否走核对轮(R-运-33)、定事件候选的颗粒度(命主本人可核到月份与部位,代看通常只能核到年份)。与缺项追问合成一次提问,不单独多占一轮。
- **节奏**:一次最多问 1~2 个最关键的问题,得到回答再决定下一个问题。缺多项时按 时刻 → 地点 → 性别 的优先级逐个补,不把整串问题一次甩给用户。
- **先铺垫再问**:盘已排出时,提问前先用一两句不依赖提问即可断出的盘面信息做铺垫(日主、月令、显著特征),再自然带出问题。例如:「这盘甲木生腊月,底子偏寒——先问一句:十来岁那年是不是住过院?」出生信息还不全、盘未排出时没有铺垫可用,直接问缺项即可。
- **缺时刻**:「时辰决定时柱,差一个时辰就是另一张盘,出生时间得精确到小时。大概几点出生?(『早上 8 点半』『下午 3 点左右』都行)」若用户确实记不清:「那我按该时段的两个相邻时辰各排一张,哪些结论会随时柱变化、哪些不受影响,分开说明。」
- **缺地点或地点无法解析**(退出码 2):「出生地用来换算真太阳时,差一个经度时辰就可能变。生在哪个城市或县?(如『四川成都』『浙江义乌』)」
- **缺性别**:「性别决定大运顺排还是逆排,补一下性别。」
- **场景判定**(断运、回溯类问题先问):「这盘是您本人看,还是替别人看?本人或知情人在场、能核对以往的事吗?」——定人称、定能否走核对轮(R-运-33)、定事件候选的颗粒度(命主本人可核到月份与部位,代看通常只能核到年份)。
- **时间格式错误**(退出码 2):照 stderr 提示转述,不自行猜测改写。
- **库内部错误**(退出码 3):把 stderr 原样报告给用户,**不要猜盘**,不要凭印象编造四柱。
- **授权不可用**(退出码 4):把 stderr 原样转述给用户(次数用尽 / 已到期 / 授权文件被改动)。**不要尝试绕过或猜测授权状态**;需要续期请用户联系授权方(见 LICENSE.md)。
@@ -66,7 +70,7 @@ python scripts/query_shensha.py --gender 女 \
|---|---|---|
| 0 | 成功 | 读 stdout 的 Markdown,进入解释 |
| 2 | 输入不可用(出生地无法解析 / 时间格式错误或缺时刻) | 读 stderr 的提示,**向用户追问**后重试 |
| 3 | 库内部错误 | 把 stderr 内容原样报告给用户。**不要猜盘**,不要凭印象编造四柱 |
| 3 | 库内部错误 / 运行环境不符(Python < 3.10) | 把 stderr 内容原样报告给用户。**不要猜盘**,不要凭印象编造四柱 |
| 4 | 授权不可用(软锁:次数用尽 / 已到期 / 授权文件被改动) | 把 stderr 原样转述给用户,**不要绕过** |
## 授权与分发
@@ -103,13 +107,13 @@ stdout 的 Markdown 依次包含以下章节。标题是解释规则的定位锚
- **节气边界提示**:出生真太阳时距交节不足 12 小时时,命盘开头出现 ⚠️ 提示。月令对出生记录误差敏感,误差超过提示值则月令改变、四柱全变;解释须声明此敏感性,断运证伪回查(R-运-33 第 4 步)时重排另一月令之盘对照。
- **夏令时**:1986–1991 年全国夏令时期间(每年 4 月中旬至 9 月中旬)出生者,钟表时间先回拨 1 小时再作后续修正——「钟表 23 点 ≠ 真太阳时 23 点」,是否晚子时以真太阳时为准(「排盘审计」段有「夏令时:是/否」)。
## 解释规则(rules/ 目录,库版本 3.5)
## 解释规则(rules/ 目录,库版本 3.6)
取格、用神、断运等解释规则在 `rules/` 下,共 20 个文件、542 条编号规则,以《子平真诠》格局法为骨架,并蒸馏《滴天髓阐微》《穷通宝鉴》《命理探源》《三命通会》四书为格局定论后的参看层(性情/事类/六亲女命增补、调候、神煞书证、旺衰扶抑、童限;拓展条均逐条标注【拓展】);`rules/sources/` 按书归档五书原书全文可供回查,书目登记见 `rules/sources/README.md`。格式规范与锚点约定见 `rules/README.md`。
**执行顺序**:
0. **问题归类**:判定用户所问的主线(健康/感情/财运/事业/学业/六亲)、前瞻或回溯、以及场景(命主本人/替人看、能否核对——见 Intake 场景判定)。次级关注(隐藏线)只作附带:输出时以一条「顺带看了 X 这条线」声明并简答,不铺成第二主线;
0. **问题归类**:判定用户所问的主线(健康/感情/财运/事业/学业/六亲)、前瞻或回溯、以及场景(命主本人/替人看、能否核对——见「Intake 对话式询问」场景判定)。次级关注(隐藏线)只作附带:输出时以一条「顺带看了 X 这条线」声明并简答,不铺成第二主线;
1. 读命盘 Markdown,加载 `rules/00_总纲_取格.md`,按 §1 六步决策流程定格;
2. 命中后加载对应分格文件(`rules/11_正官格.md` … `rules/19_杂格.md`),判成/败/救/应、用神相神、格局高低;
3. 断运时加载 `rules/90_行运.md`(§7 断运操作序列定喜忌应期,§8 事类落地把关键流年译成现实事件候选,§9 断年核对回路,§10 童限)与分格文件的「取运」节;覆盖多个流年的批量断运按 R-运-33 **核对前置**——先以场景判定分流,可核对者先锚点核对、不可核对者直推,输出只出现一次。**推断任一具体流年/流月前,必须按 R-运-34 五步核对重新打开规则文件查表,不得凭会话记忆推断**;编号记录只列本轮实际查阅的条目(R-运-35),收调试层(见「调试与溯源」);
@@ -134,6 +138,8 @@ stdout 的 Markdown 依次包含以下章节。标题是解释规则的定位锚
> 以上内容由灵爻妙解依据古籍《子平真诠》制作技能,ai生成,仅供娱乐参考,不替代医疗、法律、投资、心理咨询等任何专业意见。灵爻妙解,传承易学智慧,欢迎访问 https://lingyaomiaojie.com
**共建提示(首次讲解后)**:本次会话的第一次完整讲解(第 1–6 段全部输出完毕)之轮,在免责引用块**之前**顺带一句共建提示——第 6 段引用块保持一字不改、仍在全轮末尾;**同一会话只提示一次**,后续问答轮不再重复。口吻延续老师傅人设,自然一句带过,不写成广告,参考:「这盘先看到这。若愿意为这门手艺出份力——会话结束后直接发我『推送』二字,会把脱敏后的盘面存入共建档案库,用来校准后续版本;推与不推,都不影响看盘。」用户回应「推送」(或「推送黄金集」等明确意图)后,进入「档案共建(share/)」节既有流程:导出过目 → 授权问答 → 推送授权话术 → 推送计励。
**★边界声明的次数上限**:单轮回答中「这一层我给不出 / 这不是干这个的 / 硬报数字就是忽悠」型的方法边界说明**至多出现一次**,且必须并入第 5 段,不得另起一段、不得打断解读节奏。其余场合一律改用模糊语自然带过(见「文风」节)。声明本身不得写成辩解或自嘲。
**阶段纪律**:落笔之前遇下列情形,**必须先向用户声明分歧再继续**——
@@ -148,10 +154,10 @@ stdout 的 Markdown 依次包含以下章节。标题是解释规则的定位锚
## 断运交互(核对前置)
用户问「过往发生了什么 / 哪几年是转折」这类覆盖多个流年的问题时,按 `rules/90_行运.md` R-运-33 执行**核对前置**——所有提问发生在铺开断语之前,输出只出现一次:
用户问「过往发生了什么 / 哪几年是转折」这类覆盖多个流年的问题时,按 `rules/90_行运.md` R-运-33 执行**核对前置**——所有提问发生在铺开断语之前,输出只出现一次。核对同样走对话式询问(见「Intake 对话式询问」):不用结构化工具、不列编号选项,一次最多问一两个锚点,答完再定下一个;R-运-33 的核对程序(锚点选取、候选排序、证伪回查)照旧执行。
1. **先定场景**:intake 一问分流(命主本人还是替人看、能否核对过往),与缺项追问合成一次提问;
2. **可核对 → 锚点核对**:挑 3 个左右锚点年(组数最多、落在人生阶段窗口、用户所问之线各占其一),每个锚点年一个问题,选项为按可能性排序的 2–3 个候选事件、外加「都对不上」(证伪入口);几个锚点年合成一次结构化提问,不逐条单独打断。断语涉及学业年份时,学制锚点并入同一次提问,不单独多问一轮。核对后按 R-运-32 第 4 步收敛,一次性输出完整断运。无询问工具的环境,在正文列出编号选项请用户回复编号;
1. **先定场景**:intake 一问分流(命主本人还是替人看、能否核对过往);
2. **可核对 → 锚点核对**:挑 3 个左右锚点年(组数最多、落在人生阶段窗口、用户所问之线各占其一)。每问先给铺垫——该年盘上的显著信号一两句——再自然带出按可能性排序的 2–3 个候选事件,外加「都对不上」(证伪入口);用户答完再挑下一个锚点。断语涉及学业年份时,学制锚点顺嘴并入当轮提问,不单独多问一轮。核对后按 R-运-32 第 4 步收敛,一次性输出完整断运;
3. **不可核对 → 直推**:命主不在场、不知情,或用户明言测试、「不用问、直接说」时,跳过核对,一次性输出最佳推断——直答给主答案与置信度,全量候选收分析推理段。
锚点全部落空时先回头查组数判定、阶段假设、时辰边界与节气边界,不硬铺(R-运-33 第 4 步)。
@@ -189,15 +195,19 @@ stdout 的 Markdown 依次包含以下章节。标题是解释规则的定位锚
`python scripts/memory_lookup.py --birth "1990-05-14 08:30" --place "四川省成都市" --gender 男`
(亦可按 `--name` / `--pillars "丁亥 乙巳 庚子 辛巳"` 任意组合检索)。有档则读档延续——此前的归纳、已核实/已证伪反馈在分析推理时直接参用,已证伪的断法不得再断;无档则正常排盘解释,解释完成后用 `python scripts/memory_save.py --name ... --gender ... --birth ... --place ...` 建档(建档即一次排盘,授权副本照常扣次)。
- **回写纪律**:用户核对或澄清了任何断语后,当轮把结果写回该档案的 `## 反馈与澄清` 小节,每条以状态标签开头——推测性归纳标【未核实】,命主确认改【已核实】,被否改【已证伪】并补一句实际情况;结构性结论同步更新 `## 归纳` 各行。
- **换盘纪律(工作盘唯一 + 变更留痕)**:经用户确认换盘(日界规则分歧、时辰/出生地校正等)后,**必须当轮重排并把档案 `## 盘面` 段整体替换为新盘**——档案任何时候只有一个工作盘,旧盘不得留在盘面段,防止续推时误用。操作:
`python scripts/memory_save.py --update-chart <档案路径> [--day-boundary 子正] [--birth "校正后时刻"] [--place "校正后地点"]`
(重排一次,授权副本照常扣次;frontmatter 四柱/日主同步为新盘,四柱变动时文件自动改为新主键名;目标档案已存在则拒绝覆盖)。留痕:旧盘四柱、换盘原因、确认方式与时间记入 `## 反馈与澄清` 校订条目;凡受变动柱(如日柱/时柱)影响的已有推断条目(`## 归纳`、`## 流年大事` 各行),同轮标记【待复核】,复核前不得继续引用。
- **隐私**:档案属命主个人信息,只存本机、不随授权副本分发、档案原文不进 share;不得把档案原文外发(不粘贴到外部对话、不上传网络、不写入其他文件)。回传授权方的只有按下节规格生成的结构化脱敏包,且必须经用户授权。
## 档案共建(share/)
用户可自愿把**脱敏后**的命盘数据回传授权方,用于技能优化与规则蒸馏(脱敏规格、隐私协议与撤回方式见 `share/README.md`)。每成功推送一盘,本副本授权次数 **+10**;同一盘(按盘 hash)只计一次,不重复加次。
- **导出**:`python scripts/share_export.py --archive <档案路径>`(或按 `--birth/--place/--gender` 检索定位),生成结构化 JSON 脱敏包到 `share/pending/<盘hash>.json`。完整度门槛:性别/四柱/大运齐全 + 至少一条反馈事件(任意核实状态),不满足则拒绝导出(退出码 2)。**未核实推测不得入包**:归纳小节的推测性结论一律不导出;反馈事件(带核实状态标签)可入包,自由文本(反馈原文、盘面细节、归纳文字)一律不入。
- **导出**:`python scripts/share_export.py --archive <档案路径>`(或按 `--birth/--place/--gender` 检索定位),生成结构化 JSON 脱敏包到 `share/pending/<盘hash>.json`。完整度门槛:性别/四柱/大运齐全 + 至少一条反馈事件(任意核实状态),不满足则拒绝导出(退出码 2);事件简介缺失(档案未写事件内容)不挡导出,包内如实反映。**未核实推测不得入包**:归纳小节的推测性结论一律不导出;反馈事件与流年大事(带核实状态标签)连同事件简介(note)可入包。脱敏纪律:姓名一律删除;出生信息只留年月日与时辰;地域保留到城市级(省+地级市,区县及以下删除);事件简介中**城市级地名保留**(方位信息供规则蒸馏定位),真实姓名、详细住址(小区/门牌/街道号)、身份证/电话等直接定位信息一律删除——脚本自动脱敏,书写事件简介时也只写到城市级;归纳文字、盘面细节等其余自由文本一律不入。**换盘清理纪律**:换盘/出生信息重大更正后重新导出前,先清理 `share/pending/` 中同一命主的旧 hash 包——盘 hash 随四柱/出生地变化,旧包即成孤儿,可能被误推;share_export.py 导出时检测到疑似残留(同出生日同性别、盘 hash 不同)会打 WARN 提示,确认后手动删除。
- **授权询问(强制)**:推送前必须先把脱敏包**全文展示**给用户,并询问是否授权推送——用户同意才执行推送;不同意则取消,脱敏包保留在 `share/pending/`(用户可随时删除),不影响技能正常使用。
- **推送**:`python scripts/share_push.py`,把 `share/pending/` 的包推送到 `share/config.json` 配置的共建远端(GitHub 与 Gitea **两条线都推**,至少一个成功即算成功;远端地址由授权方填写)。推送成功后包移入 `share/pushed/`,并告知用户新增授权次数(+10;该盘已计励过则不重复加)。推送失败(无 git / 无网络 / 远端不可达)保留 pending,不丢数据。
- **推送授权话术(宿主权限层)**:调用推送脚本时宿主会请求执行权限,请用户确认——**「点一下允许」是唯一主路径**。① **推送前先预告**:得到用户口头授权后、调用脚本前,先发一句话预告,如「接下来运行推送脚本,你的环境可能弹出执行权限确认,点『允许』即可」;② **被拦即停、零重试**:脚本被权限层拦截后不得重试(权限状态不会因重试改变),直接向用户说明并问「是否看到权限确认?点允许我就能继续」;③ 终端手动执行 `python scripts/share_push.py` 仅作为宿主静默拦截(不弹确认、直接拒绝)时的兜底,向用户提及时一句话带过,**不列为推荐步骤**;④ **话术宿主中立**:不写死任何具体宿主的权限界面名称,统一表述为「宿主会请求执行权限,请用户确认」。
## 版本与自更新
@@ -205,11 +215,14 @@ stdout 的 Markdown 依次包含以下章节。标题是解释规则的定位锚
- **更新提示(缓存制、不打扰排盘)**:每次排盘成功后,若本地缓存的检查结果已过期(24 小时)则后台线程拉一次远端 VERSION 刷新缓存(超时 3 秒、失败静默,主流程不等);缓存显示有新版本时,stderr 提示一行「技能有新版本 X.Y.Z,运行 `python scripts/self_update.py --apply` 可更新」。
- **应用更新(须用户同意)**:用户说「更新技能」时再运行 `python scripts/self_update.py --apply`——从 GitHub 拉取(失败转 Gitea),**先按 manifest.json 逐文件校验 SHA256、任一不符即中止不动本地**,通过后覆盖更新;`data/.license.json`、`memory/archives/`、`share/pending/`、`share/pushed/`、`.git` 保留不动。不得替用户自动执行 --apply。
## 盘面图(HTML)
## 盘面图(HTML,默认生成)
排盘后同步生成 HTML 盘面图(`cast_chart.py --html`):四柱主表(当前大运与流年并列对照)、大运/小运条、全量流年、当年流月,五行配色、空亡标虚线、节气边界与晚子时出警示条。模板在 `scripts/render/templates/paipan.html`,样式可直接改。
拿到出生信息排盘后,**默认立即生成盘面图、截图并发给用户**,然后才进入对话式核对与分析。流程次序:排盘(`cast_chart.py --shot`)→ 生成盘面图并发送 → 对话式核对/补缺 → 分析 → 结论。
- **给用户看图**:agent 环境具备浏览器/发图能力时,排盘后生成 HTML 并直接打开,或截图发送给用户;纯文本环境则告知文件路径。
- **生成**:`--shot` 一步完成——stdout 出命盘 Markdown,同目录出 HTML 盘面图与 PNG 截图(路径打在 stdout 末尾;`--html 路径` 可另指定 HTML 位置)。截图分级回退:环境装有 playwright 用 playwright(file:// 全页、2 倍分辨率),否则用本机 Chrome 无头截图;两者都不可用只出 HTML 并附降级提示,不影响排盘。也可单独调 `scripts/chart_shot.py <html路径>` 补截图。
- **发给用户**:以宿主支持的方式把盘面图发给用户(图片引用或文件链接);截图不可用时给出 HTML 文件路径并说明可直接打开查看。
- **重排必重生**:出生信息有任何变动(校正时辰、节气边界确认、晚子时分歧对照等)重排时,必须重新生成盘面图与截图,不得沿用旧图。
- 盘面内容:四柱主表(当前大运与流年并列对照)、大运/小运条、全量流年、当年流月,五行配色、空亡标虚线、节气边界与晚子时出警示条。模板在 `scripts/render/templates/paipan.html`,样式可直接改。
- HTML 只是 Markdown 命盘的图形化重渲染,内容以 stdout 命盘为准;解释时引用的字段名仍以 Markdown 章节为准。
## 文风与反 AI 腔(强制)