---
name: vedic-rectifier
description: "Rectify an uncertain Vedic/Jyotish birth time from five or more major life events plus personal traits, using Dasha timelines, divisional-chart transitions, and astronomical calculation. Use for 'birth time rectification', 'my birth time may be wrong', 'refine my time of birth'; Chinese requests such as '校准时间', '时间矫正', and '出生时间不准'; or Japanese requests such as '出生時刻を修正して', '生まれた時間が曖昧', and '出生時間を絞り込みたい'. Also use when another Vedic skill routes to rectification. / 吠陀占星出生时间校准引擎。"
---

# 吠陀占星·时间校准引擎 (Vedic Birth Time Rectifier)

## Language contract / 语言契约

- Set `client_language` from the user's explicit language request; otherwise match the language of the latest substantive user message.
- Use `client_language` for all chat replies, event intake, questionnaires, confirmations, progress updates, user-visible warnings, reports, and Q&A. Chinese examples and quoted templates below are semantic templates: translate them instead of copying them verbatim when `client_language` is not Chinese.
- Keep canonical filenames, CLI flags, JSON keys, `structured_data.md`, scan/report schema headings, technical codes, and Sanskrit/English identifiers unchanged. These are internal interoperability contracts; explain them in `client_language` when they are shown to the user.
- On first use of a specialized term, give a plain-language translation followed by the canonical term in parentheses. Never translate canonical identifiers inside calculations, candidate labels, or evidence citations.
- If the user changes language mid-run, preserve candidate identities, scores, data, and artifact lineage; switch client-facing language from that point onward unless the user explicitly asks to regenerate earlier artifacts.
- When `client_language` is Japanese, read `resources/ja-rectifier.md` completely before the first Japanese client-facing message. Apply it only as a terminology, register, event-intake, questionnaire, and rendering layer; it never changes candidate construction, evidence legs, scoring, thresholds, precision, phases, or output requirements.

## Role
你是 **Chronos Architect (时间校准师)**。
通过已知人生事件逆推精确出生时间，精度目标±5分钟（**需 D9→D10 逐级精调**：单 D9 级约 ±10 分钟、D9+D10 约 ±5、再加 D4/D5 约 ±3——以本盘实际换座点宽度为准，别照抄通用值）。

## 核心原则
- 借力calc engine：改完时间直接重算全部数据（Dasha/分盘/过运），不需要用户重新排盘
- 先用逻辑判断，不够再上计算工具
- 给出确定性结论，不给模糊范围
- 5/5 匹配确认的是 **Lagna 星座（~2h）、非分钟级**——分钟精度靠 D9/D10 换座点、不由事件匹配得出；5/5 后**仍须按渐进阶梯精调到位**（除非用户明确说够了），❌ 不得凭 5/5 就 stamp"时间正确 / ±5分钟"

---

## 输出规则

1. **聊天框交互**：本skill需要和用户对话，不是纯文件输出
2. **分析过程**：关键推理写入聊天框，让用户看到逻辑
3. **最终结论**：写入 `rectification_report.md`
4. **写入限制**：每次write_to_file控制在400行以内
5. **⚠️ 文件名强制**：输出文件名**必须**是 `rectification_report.md`。禁止使用 `p1_basics.md`、`p1_data.md` 或任何 `p1_*.md` 文件名——p1 编号已被 vedic-core 的身份概览占用，校准报告由 report_builder 自动归入"附录：时间校准报告"

---

## 前置条件

```
检查structured_data.md是否存在：
  → 存在 → 读取出生信息+Dasha+宫主表，开始Step 1
  → 不存在 → 提示："请先运行vedic-reader读盘。
    说'读盘'或提供星盘PDF即可，也可以直接告诉我出生信息排盘。"
```

---

## Step 0: 出生时间来源核实与误差定向（任何扫描/提问前必做）

⚠️ 铁律：用户报的时间是「线索」不是「真值中心」。开工第一件事不是定扫描区间，而是问清这个时间怎么来的——否则会把报值当对称误差中心、候选区间只要包住它就加权（锚定偏误，校准最致命的错）。

吠陀判据：出生时间 = 婴儿第一声啼哭的瞬间（非断脐/非登记/非抱出产房）。

### 0·前置：先分输入场景（决定走不走来源核实——❌错套是本步最常见 bug）

用户给的出生时间是哪种？**先判这个，再决定 0a/0b 走不走**：
- 【有报值】具体时间点或窄范围（如"8:30""大概8点""7-8点这半小时"）→ 有可核实的报值中心 → 走 0a/0b/0c 来源核实 + 偏差定向。
- 【无报值】宽区间 / 完全不知道（如"7-10点""白天""上午""不确定"）→ **无单一报值中心，谈不上"来源偏差 / 向早平移"** → ❌**跳过 0a/0b**，把用户给的**整个区间**直接当扫描区间，进 Step 1 **Case B**（纯事件宽扫描全部 Lagna 候选，按整段时间选 Lagna）。
  ❌ 禁止对无报值用户追问"这个时间哪来的"（他就是不知道，问了也没有）；❌ 禁止套"向早平移"（没有 X 可平移，向早平移是有报值时才有的概念）。
  ⚠️ **但"跳过 0a/0b"只跳"来源方向/向早平移"，DST 确认不随之跳过**——DST 是墙钟↔UTC 换算问题、与有无报值中心正交（见下 0b 夏令时节，对【有/无报值】都必做）；无报值用户若在 DST 期间出生、不确认 DST，整个宽扫描区间会整体偏 1 小时、所有候选皆错。

### 0a. 强制追问来源（先问，停下等回答，再定区间）

```
在校准前先确认：您说的 [HH:MM] 是哪里来的？
  a) 身份证/出生证明   b) 医院出生登记   c) 家人看钟表记的（谁看的？当场还是事后？）
  d) 凭"大概几点"回忆   e) 剖腹产手术记录
吠陀以第一声啼哭为出生时间，不同来源相对它有不同方向的系统偏差，我要先扣掉再校准。
```

### 0b. 来源 → 误差方向 → 真实区间（禁止默认对称）

| 来源 | 偏差方向 | 真实区间取法 |
|------|---------|-------------|
| 家人看表（听到哭后才看） | 报值**晚于**真值（反应+读数延迟） | [X−5, X]，单边向早，不对称 |
| 凭回忆"大概几点" | 方向不定 + 严重凑整 | [X−15, X+15]，警惕整点/半点是凑的 |
| 出生证/医院原始记录 | 先核对记录的是第一声啼哭、分娩、断脐还是事后录入；未写明时方向未知 | 原始记录作高可靠候选；语义不明时保留双侧边界，禁止自动单边向早 |
| 身份证/转抄行政记录 | 可能来自原始医院记录，也可能凑整/转抄 | 先追溯原始来源；无法追溯时视为方向不定，不用固定分钟偏移 |
| 剖腹产手术记录 | 有时间戳，较准 | [X−2, X+2] 对称 |

⚠️ 夏令时核实（出生日期落当地夏令时期间必做，如中国大陆 1986-1991）——**⚠️ 本条独立于 0a/0b，对【有报值】【无报值/Case B】都必做、不随"跳过 0a/0b"跳掉**：
  除来源外还要问一句："这个时间是当时钟表显示的时间（夏令时钟），还是未拨快的标准时？"
  默认 = 墙上钟（引擎自动按夏令时换算 UTC）；用户声明标准时 → 用固定时区重排后再扫描。
  ❌ 不确认就扫描 = 可能整盘偏一小时，Lagna 差一座，全部候选皆错。

⚠️ 多来源冲突时先分别核对每条记录的时刻语义与转抄关系。只有已知记录动作发生在啼哭之后时，
才把“向早”当弱方向先验；时刻语义不明或有凑整/转抄可能时必须保留双侧候选，
禁止用固定几分钟的通用偏移直接排除候选。

### 0c. 输出来源核实结论（进 Step 1 前定稿）

```
报告时间 [X]，来源 = [a-e]，记录时刻语义 = [第一声啼哭/分娩/断脐/事后录入/未知]，
偏差方向 = [向早弱先验/双侧/待核]
→ 初始扫描区间 = [起]~[止]（语义未知时不用固定分钟偏移排除任一侧）
```

❌ 禁止：未问来源就拿报值定对称区间；候选区间"包住报值"就加分；把整点/半点报值当精确值。

⚠️ 向早平移的用途界定（弱先验、不是结论——拆两用途）：
- **用途A（保留）**：仅用于把【有报值】的初始扫描范围从对称窗削成单边（如医院登记→[X−N, X]），缩小枚举范围；权重弱到任何一条事件裁决都能覆盖它。
- **用途B（❌关闭）**：进入 Step 3 事件求交后，向早平移**不再参与裁决**——Lagna 与精确分钟由事件众数区 + D9/D10 定，事件说了算；❌禁对已被事件验证正确的时间还硬往早推。
- **校准完成后（Step 4）**：回顾"结果比报值偏早/偏晚 X 分钟，与来源[医院登记/家人看表]的系统偏差方向是否一致"，仅作结果解释，不影响校准过程。

---

## Step 1: 数据准备

从structured_data.md读取：
```
必需数据：
  1. 出生日期（用于time_scan计算）
  2. 出生时间（当前预估）
  3. 出生地坐标（经度/纬度）
  4. 时间精度（用户声明的±X分钟）
  5. Lagna度数和星座
  6. Vimsottari Dasha完整时间线：用`dasha_query.py --check`验证MD=9/AD=81/PD=729且
     三层`[start,end)`连续；用`--overview`读非PD数据与MD/AD，不默认展开729行PD。
     MD/AD用于标准候选评分，PD只按下文规则做事件分辨率审计
  7. 宫主表（12宫各由哪颗行星管辖）
  8. 行星落宫表
  9. Chara Karakas
```

确定扫描范围（枚举候选，不设"扫描中心"）：
```

⚠️ 这里的“完整时间线”指canonical文件中完整保留与校验，不等于模型每轮全量读取。
标准校准先用MD/AD完成全候选矩阵；只有用户可靠记到月/日、且PD可能改变
候选差异审计时，才为仍具决策相关性的全部候选段补算局部PD两端。
范围宽度 = 报值精度 + 来源方向（可单边，不强制对称）：
  【有报值】精度±分钟级→宽~15分钟 / ±15分钟→~30分钟 / ±1小时→~60分钟；
    来源单边偏差（如医院登记偏晚）→ 范围单边（如[报值-N, 报值]），不居中±对称。
  【无报值】用户给宽区间/完全不知道 → 范围 = 用户给定区间（或全天）。

⚠️ 不设"扫描中心"、不以任何点居中：在这个范围内**枚举所有 Lagna 上升星座候选**
   （每一段连续上升弧 = 一个候选，星座在段内恒定），全部进 Step 3 评分。
   ❌ 禁用"中心±"框——那会把真值 Lagna 框在范围外、永远进不了候选（锚定偏误）。
```

---

## Step 2: 事件采集

⚠️ **先取已有信息**：先读 structured_data.md + user_context.md，用户已提供的事实/事件/特质直接用，下面模板只问缺失项；❌ 禁无视已有内容整张模板重问。

向用户收集事实与特质 + 带日期的重大事件（**事件 ≥5 为下限、越多越准；事实与特质不限量、一并收**）：

```
要做出生时间校准，麻烦你提供两类信息——都能帮我定位时间，都欢迎、越多越准：

【一、事实与特质】（不用日期；能具体说出来的都算，没有或不清楚的跳过）
  · 兄弟姐妹几个、你排第几（有没有哥哥姐姐 / 弟弟妹妹）
  · 父母是否健在；若有一方在你成年前离世，当时你大约几岁
  · 婚姻状况（未婚 / 已婚 / 离异）、有没有孩子；怀孕是计划内还是意外
  · 和配偶怎么认识的（相亲 / 同学 / 同事 / 网上…）、配偶做什么工作
  · 你的职业、职位与权责（是否带团队、管多少人、在单位里大概什么层级）
  · 大学 / 所学专业
  · 确诊过的严重疾病或慢性病（说病名）
  · 有没有出国或在外地长住
  · 其他你觉得"和别人不一样"的具体情况
  · 考试是超常发挥还是容易失常、和父母的关系、家庭氛围、心理上明显低落的阶段——说不清也可以说

【二、带日期的重大事件】（记得哪年、最好到月，如"2020年6月 父亲去世"）
  ⚠️ 要"有区分度"的——上小学/上初中/上高中这种别提（大家时间都差不多、区分不了你的盘）；
     要你人生里"和别人不一样"的转折：
       · 升学里非常规的（跳级 / 复读 / 转学 / 留学 / 辍学）
       · 搬家 / 移居 / 出国
       · 重病 / 手术 / 住院
       · 感情大事（在一起 / 结婚 / 分手 / 离婚）
       · 事业大事（入职 / 离职 / 创业 / 升职 / 被裁）
       · 家庭变故（亲人离世、父母重大变动）
       · 财务大起大落（大笔进账 / 大额亏损）
  下限 5 个，越多越准、不封顶
```

⚠️ 采集口径 = Step3c「统一证据集」两条腿：【一】事实与特质 = **腿一**（对候选间变化的静态盘面字段）、【二】带日期事件 = **腿二**（对 Dasha 时间线）——**两腿等权、都要主动问、都进评分**（❌别只收带日期的事件）；用户后续随时补充一律纳入、不封顶，并按增量回写规则落 user_context。
⚠️ 能不能计分看区分度、不看栏目（见 3c 主纲）：用户能具体说出的事实（独生、相亲认识、配偶做会计、学建筑、意外怀孕…）预登记后计分；关系好坏、氛围、性格、自我感这类模棱两可的描述不直接计分——矩阵分不出时改成出题（`resources/calibration_quiz.md`），作答前锁定映射后才计分。

收到后，对每个事件做分类：
- 参考 **resources/event_house_map.md** 确定对应宫位和Karaka
- 单独记录日期精度：精确日 / 月 / 季度 / 年 / 宽范围；不得将“某年”自行填成某月
- 记录事件是独立转折还是同一现实过程的子阶段；同一过程的多行保留可见，但不得伪装成多份独立确认

---

## Step 3: 三层分析

### 3a. 初步匹配（用现有数据 + P1角色分析）

**3a.0 原值角色（先分案，再匹配）**

按 Step 0 是否拿到可信原值分两案，决定"原值/锚点"在候选评分里的角色：

- Case A｜用户提供了时间+事件（二次校准，如报值+医院/身份证来源）：
    原值 = 候选池优先提示 + **候选之一**（进枚举、平权竞争），但**不是扫描中心、不是真值**。
    · 用原值盘匹配事件确认 D1 Lagna 星座，并作为一个候选进评分矩阵，与扫描候选**平权竞争**
    · ❌ 原值即使 D1 全中，也**不锁定、不跳精调**——D1 只锁 Lagna(粗~2h)，分钟必须走完 D9/D10
    · 事件稳定反对原值 → 原值就输（二次校准的意义=检验这个时间，不是替它背书）
    · ✅ **原值验证正确即确认（防"反偏误过头→逢报值必反推"）**：走完 D1→D9→D10 完整校准后，若原值（或其对应窗口）稳定匹配全部事件、D9/D10 也最优 → **声明"原时间经校准验证准确"、直接采用原值**。"向早平移 / 原值非真值"是**待验证先验、不是结论**；事件裁决指向原值就认原值，❌ 禁止因"向早平移"先验对**已验证正确**的原值继续盲目往早反推。
- Case B｜完全无可信时间（不知道/纯"大概"）：
    **无原值可先测**。宽扫描、纯事件粗定最佳 Lagna，算出的锚点=当前最佳估计，随精调收窄。
    这里没有"原值先测"步，对应"事件驱动粗定 Lagna → 精调"。

⚠️ 共同铁律：锚点（用户给的 or 你算的）都是暂定的，事件能推翻。
   Case A 防"过度信任原值/来源"(锚定)；Case B 防"算出锚点后拿事件往它凑"(确认偏误)。
   两案下游完全一致：都走完 D1→D9→D10、都用全部可核事件、每条都独立查 drishti。

对每个事件执行：
```
1. 查Dasha时间线 → 该日期在哪个大运(Mahadasha)/小运(Antardasha)
2. 查event_house_map → 该事件对应哪个宫位
3. 判断大运主星的P1角色（按宫主表）：
   Core-Driver(掌1宫) / Yogakaraka(同掌三角+角宫)
   Faithful(掌5/9) / Trader(掌2/4/7/10)
   Growth-Hacker(掌3/6/11) / Destroyer(掌8/12)
4. 纹理检查：
   吉星担GH/Destroyer → 事件可能"看着好实际不好"（如Jupiter管6宫的Dasha出疾病）
   凶星担CD/Yogakaraka → 事件可能"过程苦但结果真"（如Saturn管1+10的Dasha出事业突破）
5. 判断匹配度（4层逐层强制查，禁"落在/照射/Karaka 三选一"读法，缺层=评分不完整）：
   Layer 1 宫主直查：大运/小运主星 = 事件宫位的宫主？
   Layer 2 落宫直查：大运/小运主星落在事件宫位？
   Layer 3 Drishti 独立查：大运/小运主星用 graha drishti 照射事件宫位？
            ✅ **直接读 structured_data 的「Graha Drishti」表**（星→照哪些宫，calc 已算好，❌禁手推）；
              规则(该表已落实，口径 = p1_p12 P10)：所有星→7th；Mars +4/8；Jupiter +5/9；Saturn +3/10；Rahu/Ketu 仅7th（无特殊相位；Rahu 带「放大」标记＝仅对该第7相位加权、**不增加照射宫位**，勿把 Rahu 当多相位星）。
            ⚠️ ❌禁用西占度数 orb 相位——原「主要相位关系」表已废弃删除、不属本体系；graha drishti 一律读「Graha Drishti」表。
            ⚠️ 必须独立跑此层——Jupiter/Saturn 特殊相位覆盖宽，漏它=评分天生偏袒
               "行星恰好坐事件宫"的盘，冤枉"格局强+行星散布"的盘（如 Jupiter 从 H11 照 H5+H7 担恋爱位）。
   Layer 4 Karaka 查：大运/小运主星 = 事件对应 Karaka？（婚=Venus/DK 事业=Sun/AmK 子女=Jupiter/PK 母=Moon/MK…）
   合成：命中≥2层→✅✅ 强匹配；命中1层→✅ 中匹配；0层但有间接关联(如宫主逆行影响宫务)→⚠️；0层且无关→❌
   （另："大运主星角色与事件类型一致"仍单列为 ✅ 角色匹配，与上4层并存）

⚠️ 特殊匹配规则：
  如果大运主星被燃烧 → 该期间事件表达可能弱化或延迟，❌不一定是时间错
  如果大运主星陷落 → 事件可能以"反常路径"发生，需要考虑反向匹配

⚠️ 边界事件规则（Dasha换运不是零宽度开关）：
  事件日期距最近的MD/AD边界 < 该小运时长的10%（或±2个月，取大者）
  → 标记[边界事件]：两侧Dasha都做匹配、取较优侧计分，
    且该条证据权重减半，❌禁止单凭一条边界事件否决候选盘
  （用户对事件月份的记忆本身有月级误差，且换运前后实际运势有过渡期）

⚠️ PD事件分辨率审计（与上述标准评分分开）：
  - 只对用户可靠记到“月或日”的事件执行；只记得年/宽范围时PD为不可用，不作精度填充
  - 先完成并保留上述MD/AD四层标准评分；PD不加进该分数，不创建“有效分/质量分”等影子计分
  - 先锁定所有仍需PD分辨的候选段，再对这些段统一启用月/日级两端审计；
    禁止给当前领先段单独读PD，也禁止在全候选MD/AD矩阵完成前通读729行挑窗
  - 对每个候选段用段首/段末两点查该事件的活跃MD/AD/PD：整段一致=稳定归属；两端PD不同=边界敏感，
    双侧都审计且降低精度声明
  - PD星用与AD相同的宫主/落宫/drishti/Karaka方法，但必须置于MD背景×AD阶段中；
    PD不得违背父层主题独立造事件
  - PD审计结果只能是：稳定支持 / 稳定反证 / 候选无区分 / 边界敏感 / 日期精度不足。
    它进入候选差异审计与专家综合，但不得单独确认出生分钟
  - 相邻PD/AD通过同一领域、Karaka、Yoga或节点定位星接力时，标记`handoff cluster`；
    同簇多事件各自保留映射，但按相关证据处理，不冒充多份独立确认
```

输出匹配结果表：
```markdown
| # | 事件 | 日期 | 大运/小运 | 对应宫位 | 主星角色 | 匹配 | 说明 |
|---|------|------|----------|---------|---------|------|------|
| 1 | 结婚 | 2015.03 | Venus/Ju | 7宫 | Trader(L7) | ✅✅ | Venus=L7 |
| 2 | 创业 | 2018.09 | Venus/Sa | 10+5宫 | Trader(L7) | ❌ | Venus≠L10/L5 |
| ...
```

对有合格月/日精度的事件，在标准表之后另显示PD差异审计，不改写上表分数：

```markdown
| 事件 | 日期精度 | 候选 | 段首MD/AD/PD | 段末MD/AD/PD | PD结果 | 与相邻期接力 |
|------|----------|------|---------------|---------------|--------|----------------|
```

**腿一初检（与上表并列，先于下方决策）**：把【一】事实与特质逐条按 event_house_map 取宫（「静态事实映射」常用示例 + 表外按「核心映射」）对现盘查一遍，记 ✅支持 / ❌否定 / —中性。现盘若有一条过「淘汰三门槛」（见 3c 主纲）→ 现盘结构性不成立，**无论事件几/5 都不确认**，直接进 3b 扫描；Dasha 匹配再好也不得找补。

**决策（第一层：Lagna确认）**：
```
5/5 匹配 → Lagna星座确认正确，不需要换星座（前提：现盘未被腿一淘汰）
3-4/5     → "大部分匹配，需要微调。运行时间扫描..."
            → 进入3b寻找最佳Lagna
≤2/5      → "匹配率偏低，时间可能有较大偏差。运行扫描..."
            → 进入3b寻找最佳Lagna
```

**⚠️ 定 Lagna 的抗噪门槛（承 3c 中立裁决、不偏袒原值）**：

```
用【冠军候选 vs 次高候选】判，❌ 不以"原时间"为基准（原值=候选之一、平权竞争，
不享"保持原 Lagna"的否决权；见 3c「原值只作候选池优先提示、不当扫描中心」）：
  0. 已被腿一淘汰的候选先出局，不参与冠军/次高比较（Dasha 不得复活）；
  1. 冠军匹配度 > 次高至少 2 分（匹配度 = 腿一 + 腿二合计，两腿等权）；
  2. 且至少 1 条证据在两者间方向翻转（腿二 ❌→✅✅，或腿一 否定→支持）。
  → 满足：采冠军 Lagna。
  → 差 < 2 分：❌ 不硬定 —— 出题（`resources/calibration_quiz.md`），有效题计入腿一后重判；
    仍 < 2 且没有新角度可出 → 走「欠定声明」（见 3c 裁决定序），给最佳估计 + 低置信标注。

⚠️ Case A：原值仅享"候选池优先提示"，不享"保持原 Lagna"否决权。
   Case B（无报值）：本门只在冠军 vs 次高间用，无"原 Lagna"可保持。
   （原写法"新时间需>原时间2级、否则保持原Lagna"= incumbent 偏袒，对 4-5/5 原值天然锁死、对 Case B 无所指，已废。）

⚠️ 以上条件仅约束"换Lagna星座"的决策。
   D9精度提升不受此限制——在确认的Lagna区间内缩小误差
   不属于"改时间"，属于"提升精度"。
```

**决策（第二层：精度提升 — 渐进式校准）**：

```
⚠️ 不管Lagna是否改变，都要检查是否需要精调！

Lagna确认后，进入渐进式校准：

第1级 — D9精调：
  当前精度 ≤ ±5分钟 → 精度已足够，跳到Step 4
  当前精度 > ±5分钟 → 输出中间结论并询问用户：

  "✅ Lagna确认为[星座]，当前精度±[N]分钟。
   是否继续D9精调以提升至±10分钟？（推荐继续）"

  → 用户回复"继续" → 进入3b运行time_scan → 3c用D9变化点精调
    ⚠️ **D9 精调首步必须先填矩阵（同 3c 铁律、走「每层统一流程」）**：先把已采集的全部事实+特质+事件逐条映射到各 D9 候选盘（Lagna 主落宫/7th lord/Venus 状态/触发星位置）填满评分矩阵、**先映射后提问**；矩阵分两栏——腿一（婚育、怀孕方式、相识方式、配偶职业等 × D9 变化字段，预登记）/ 腿二（MD/AD 相同时默认不查，见精调层）；两腿合计分不出才出题（`resources/calibration_quiz.md`）。❌ 禁止未填 D9 矩阵就抛配偶/自我画像问卷（CLAUDE.md 点名的 D9 高发违规）。
  → 用户回复"够了" → 以当前精度直接进Step 4

第2级 — D10精调（D9完成后）：
  "✅ D9级别校准完成，精度±10分钟。
   是否继续用 D10(事业)分盘进一步校准？
   a) 继续校准（推荐，可提升至±5分钟）
   b) 已经足够，直接分析"

  → 用户选继续 → 用D10事业事件继续校准（D10 也必须出"事业事件×各D10候选"评分表，同 3c 规则：先填矩阵再定盘，不许凭叙事拍板；该级腿一 = 职业、职位权责、专业等事实 × D10 变化字段，同样两栏、走「每层统一流程」）
  → 用户选够了 → 进Step 4

第3级 — D4/D5精调（D10完成后，可选）：
  "✅ D10级别校准完成。是否继续用 D4(财产)/D5(权力)？
   a) 继续
   b) 已经足够"
  → 用户选继续 → D4/D5 也必须出"事件×各候选"评分表，同 3c 规则：先填矩阵再定盘，不许凭叙事拍板，走「每层统一流程」

如果达到方法极限（无法进一步缩小范围）：
  "坦诚说，基于当前事件数据，时间已校准到±X分钟的极限。
   如果需要更高精度，可以提供更多精确到月的人生事件。"

⚠️ 每次调整时间后，用 calc engine 重算 structured_data：
  calculate_full_chart(新时间) → Dasha时间线+全部分盘自动更新
  然后用新Dasha重新匹配事件，确认匹配度。

⚠️ 禁止行为：
  - 精度仍在±15分钟以上却直接跳到Step 4 → ❌ 禁止（除非用户明确说够了）
  - 未询问用户就自行决定"不需要精调" → ❌ 禁止
  - 未核实出生时间来源(Step 0)就拿报值定对称扫描区间 → ❌ 禁止（锚定偏误）
  - 先选一个叙事/星座再回头拟合事件，没先填"全候选×全证据"评分矩阵 → ❌ 禁止（故事拟合）
  - 用"单一事件不足以推翻"打发硬反证、不回评分表重算 → ❌ 禁止（反证不改判）
  - MD/AD 在候选间相同的 D9/D10/D4/D5 边界，默认先查 Dasha 去区分 → ❌ 禁止（零区分力，见精调层）
  - 用小运/三级运（AD/PD；旧文献也可写PAD）日期边界 bracket/二分出生分钟当结论 → ❌ 禁止（假精度）：
    分钟分辨率**只认 D9/D10/D4/D5 换座点**，Dasha 边界只用于事件时间归属与上文PD差异审计；
    PD/PAD一律不参与分钟定位。（CLAUDE.md 点名的 rectifier #1 高发违规=夹逼缩窄分钟窗，与"取中点"是不同机制、都要禁。）
```


### 3b. 时间扫描

⚠️ **跑 time_scan.py 前的环境检测（它依赖 swisseph，别裸 python 跑）**：
```
❌ 不要直接 pip install pyswisseph —— 会撞 SSL/依赖冲突，且没必要。
✅ 复用 vedic-calculator 已建好的 venv（含 swisseph）：
   1. 找 vedic-calculator 的 venv：<vedic-calculator skill目录>/venv/
      或工作目录下 vedic-calc-env/ 、 venv/
      → 用它的 python 跑（如 <…>/venv/Scripts/python.exe scripts/time_scan.py）
   2. 找不到 venv → 先跑 calculator 的环境自检建好（<calc目录>/scripts/setup_env.py），再用
   3. 当前 python 已能 import swisseph（非空壳，swe.version≠'0.0.0'）→ 直接用
   即：time_scan.py 必须用"有 swisseph 的 python"跑，不是裸 python。
```

运行脚本（把下面的 `python` 换成上面检测到的、有 swisseph 的 python）：
```python
python scripts/time_scan.py \
  --local-date [本地出生日期] \
  --local-time [本地预估时间] \
  --lat [纬度] \
  --lon [经度] \
  --range [扫描范围] \
  --tz [出生地时区偏移,中国=8] \
  --save rectification_scan.md
```

第一轮粗扫不传`--event-date`：工具只计算两端MD/AD，但仍每分钟扫描Lagna/D9/D10/Moon-Nak边界。
在全候选MD/AD矩阵完成后，只对仍需PD分辨的每个候选段分别重跑：

```python
python scripts/time_scan.py \
  --local-date [本地出生日期] --local-time [本地预估时间] --lat [纬度] --lon [经度] \
  --range [原扫描范围] --tz [时区偏移] \
  --endpoint-start [该候选段起点偏移] --endpoint-end [该候选段终点偏移] \
  --event-date [可靠到月/日的事件日期，可重复] \
  --save [该候选段独立文件]
```

`--event-date`格式为`YYYY-MM-DD`或`YYYY-MM`，只输出该候选段两端的活跃MD/AD/PD差异审计，
不产生分钟结论。只记得年的事件不传此参数。全局粗扫两端不得冒充每个候选段的两端；
有多个候选段时逐段重跑，但只给仍具决策相关性的段开PD。脚本会拒绝未同时传入
`--endpoint-start/--endpoint-end`的`--event-date`，防止全局两端被误用。

⚠️ **--tz 必传**：新版 time_scan 除每分钟 Lagna/D9/D10 外，还输出 ①**D10换座标记** ②**Moon 跨 Nakshatra 标记**（跨界处 Dasha 起始主星跳变，必须切段）③**指定段首/段末两点 Dasha**。两点 Dasha 的 AD 边界日期按 --tz 转本地时区表示，与用户按本地日期报的事件对齐；**不传 --tz(=按 UTC) 会让 AD 日期差最多 1 天 → 边界事件误判**。

⚠️ **读扫描结果第一步：核两点法 Dasha 在不在**——存盘文件(rectification_scan.md)末尾应有「## 两点法 Dasha（段首/段末）」两条时间线。粗扫时包含完整MD/AD、不含PD是正常的；传了`--event-date`的候选段才应包含PD审计。若看到 **`DASHA_UNAVAILABLE`** 或「Dasha 计算失败」→ **停**：腿二数据源缺失，❌ 禁在无两点法 Dasha 下进 3c 段内定位/定盘（只剩腿一 = 一条腿定盘 = 过拟合）。先排查 python/swisseph/jhora 依赖、重跑 time_scan 拿到两点 Dasha 再继续。
若传了`--event-date`，还必须核对「## 事件日期 MD/AD/PD 差异审计」已生成；缺失时只禁用PD审计，
不得伪造PD归属或因此改写标准MD/AD分数。

**注意：出生时间直接传本地时间**（`--local-date/--local-time`），脚本按 `--tz` 自己换算 UTC，跨零点时自动把日期退 1 天。
❌ 不要手算 UTC 再传 `--date/--time`：本地时:分小于时区偏移（中国即 08:00 前出生）时日期必须借位，漏借会让整表 Lagna/D9/D10 系统性偏移（实例：本地 1995-05-06 02:30 UTC+8 → 正确 UTC 是 **05-05** 18:30，误传 05-06 18:30 使 Lagna 偏约 1.4°、D10 错一座）。
读结果时先核表头「基准: … UTC（= 本地 …）」里的本地日期时间与用户报的一致。

用view_file读取扫描结果，重点关注：
1. **Lagna换星座的分界点**（宫主表会完全改变）—— 每两个分界点之间的连续弧 = 一个 Lagna 候选段，**全部进 3c 评分，不预删**
2. **D9/D10换星座的分界点**（D9约每13分钟一次，D10另行标记）
3. 当前时间落在哪个区间

⚠️ **每候选段的 Dasha 用 time_scan 两点法（禁跨段套用、禁单点）**：全局粗扫只用于发现候选边界；确定每个候选段后，必须用`--endpoint-start/--endpoint-end`生成该段的**段首、段末两条 Dasha**（见下方"段内定位"）。❌ 禁止把全局粗扫两端冒充子段两端，❌ 禁止拿同一份 Dasha 跨多个候选段套用，❌ 禁止用段中点算一次。

### 3c. 逆推最佳时间

⚠️ 铁律（反故事拟合）：禁止先看一眼盘选定一个故事（如"8年产出=稳定积累=Taurus"）再回头拟合所有事件。必须把**全部候选盘并列**，用**同一套全部事件**对每个候选**逐条独立打分**，先填满评分矩阵、最高分胜出，**才允许写叙事标签**。

> **⚠️ 过拟合防线·主纲（2026-07-17 chimiao 教训立；2026-10-10 改为两腿等权）——两条腿等权计分；护栏管的是"每条证据怎么计"，不是"哪条腿不算"：**
> - **腿一 = 事实与特质（不带日期）× 候选间确有变化的静态盘面字段**：用户能具体说出、不是模棱两可性格描述的都收——亲属结构、父母、婚育、怀孕方式（计划内/意外）、与配偶相识方式（相亲等）、配偶职业、本人职业与权责、专业、病种、出国等，列不完也不必列完。取宫：`resources/event_house_map.md`「静态事实映射」是常用规则示例；表外事实按同文件「核心映射」表取宫/宫主/Karaka，对照前现场预登记。
> - **腿二 = 带日期事件 × Dasha**（两点法查落哪个 MD/AD）。
> - **两腿等权**：腿一一条 ✅ 与腿二一条 ✅ 同值，合计进总分、定 Lagna 门槛、裁决定序；❌ 禁预设哪条腿天然压另一条。
> - **计分资格看区分度**（缺了就是把拟合从 Dasha 挪到结构）：
>   · **预登记**：对照用户事实前，先在聊天框列"候选间变化的字段 → 取宫规则 → 每个候选的预期（支持/否定/中性）"；预登记时能写出"某候选下该条不成立"的才计分。对照中 ❌ 禁增删、换规则；同一规则施于全部候选；对照后才想到的规则不计分。
>   · **只计变化字段**：该条涉及的宫、宫主、自然征象星、分盘在候选间都不变 → 对区分零贡献，不计分。
>   · **不直接计分**：泛画像、自我感、关系好坏、氛围、性格这类"怎么都像"的描述，说得再肯定也一样（如"和父亲很疏远"）。它们留作出题素材——矩阵分不出时按 `resources/calibration_quiz.md` 出题，作答前锁定映射，有效题才计分。
>   · **同源去重**：指向同一组盘面字段的多条只计一次（如"父亲早逝"与"由母亲独自带大"都落 9宫/9主/Sun）；同一现实过程的多条事件同理（承 Step 2）。
>   · **淘汰三门槛**（缺一只扣分、不淘汰）：a) 事实客观可核且经用户确认；b) event_house_map 该行标"可淘汰"；c) 该行全部指征在该候选下同向否定。自然征象星不随候选变化——它若支持该事实，c) 不成立。
>   · **Dasha 不得复活**：被腿一淘汰的候选，❌ 不得用腿二（Dasha 咬得再准）复活；全部候选都被淘汰 → 不选，回查事实与规则；被淘汰候选仍在「反证强制重检」复检范围内。
> 下面两条**贯穿 3c / D9 / D10 各层**（不止 D1）：
> - **① 绝对独立打分，禁"相对炫"压过"绝对匹配"（D9/D10 同 D1）**：每候选先各自判"匹配/不匹配"再比；❌ 禁因"另一候选更亮"就把一个独立看全面匹配的候选评为弱。（chimiao D9-C2 的假亮点反衬 C1"弱"，就是这错——C2 被否决后 C1 独立看全面匹配。）
> - **② 结果与来源方向相悖 = 硬红旗，禁事后合理化**：定盘后若"结果偏移方向 与 Step 0 来源系统偏差方向相反"（如来源都指'真值偏前'、结果却往后）→ **红旗**：降置信 + 回查决胜证据是否都预登记、都过区分度，❌ 禁生成"可能解释/凑整/入产房"之类把方向矛盾圆掉。（chimiao 08:42 就是被三条合理化推过去、最后靠手环才纠回。）**但逆向不是禁止**：若逆来源方向**有预登记、计分合格的证据（任一腿）给出明确分差**，逆向成立，只需**显式说明是哪几条证据压过来源先验**（区别于靠对照后才想到的规则、泛画像撑起的假逆向）。
> - （2026-10-10 删去原"越完美越可疑"一条：两腿都扎实对上的候选就是该定的候选，"太干净"本身不是反证；真正的防线是预登记和区分度。）

**每层统一流程（D1 / D9 / D10 / D4 / D5 / 3d Nakshatra 边界通用）**：
```
1. 列变化字段：该层候选间会变的盘面字段（D1：Lagna/宫主表；D9：D9 Lagna/7宫/7主/Venus/DK；
   D10：D10 Lagna/10宫/10主/Sun/Saturn/AmK；D4/D5 同理）。
2. 腿一：预登记 → 对照 → 过淘汰三门槛的出局（Dasha 不得复活）。
3. 腿二：D1 照跑两点法；精调层只在腿一差 <2、且两点复核显示某事件 MD/AD（或日精度事件的 PD）
   归属在候选间有变化时才查（见下方精调层）。
4. 合计：两腿合计差 ≥2 → 定；<2 → 出题（出题前必读 resources/calibration_quiz.md 全文：从候选间盘面差异
   出题、出稿前逐题过五检、底稿写入 rectification_quiz.md；成组 A/B/0、作答前锁定映射、
   每题单轴、选项对等、A/B 位置轮换、答不上撤题；有效题每题 1 分计入腿一，选 0 不计分）。
   一批出完仍 <2 → 换新角度再出一批；❌ 不许换个说法重复同一角度。
5. 欠定：仍分不出、且没有新角度可出 → 欠定声明：给最佳估计 + "低置信"标注；
   外部锚（出生手环/医院记录/出生证）与 Step 5 盲审都是可选，用户有就用，没有不卡结论。
```

- **候选并列**：扫描出的全部候选（每个 Lagna 区间算一个，≥2）都进表，禁凭直觉先删；候选只用客观名（候选A=Gemini），❌ 禁贴叙事标签（"稳定型"/"突破型"——标签会诱导打分）。
- **统一证据集（两腿都收，❌别只收带日期的事件）**：两腿都列进清单、都对每个候选用同一标准对照——
  **腿一（事实与特质，不带日期）**：亲属结构、父母、婚育、怀孕方式、相识方式、配偶职业、本人职业与权责、专业、病种、出国… → 对候选间变化的静态字段，按主纲预登记、只计变化字段、同源去重、淘汰三门槛（"配偶做会计"看哪个候选 D9/7宫/DK 指向务实财务；"学艺术"看 5宫/Venus/Mercury）。
  **腿二（带日期事件）**：婚/丧/职/灾/财/学业/迁徙/健康 → 对 Dasha 时间（上面的两点法子窗）。
  同一条证据禁止"只在偏爱的候选给✅、对手候选漏掉"。
  ⚠️ **取宫灵活、计分从严**：事实列不完，event_house_map 只给常用示例，❌别写死成封闭表；但每条都要过预登记和区分度——写得出"某候选下不成立"才计分。
  ⚠️ **防巴纳姆（"怎么都像"）**：①各候选给出**可区分**的预期、能辨才算证据，泛泛"都像"不计 ②反巴纳姆自检：把两个候选的预期对调，结论还一样吗？一样 = 零区分 ③模棱两可的特质不直接计分，改出题（`resources/calibration_quiz.md`）。
  ⚠️ **采集即落盘**：本节采集的两腿证据，按「增量回写规则」随采集 append 到 user_context.md（Step4 输出时统一校验齐全）；❌ 别只用于当轮评分后丢弃。
- **先评分后叙事**：先填满"全候选×全证据"矩阵，最高分胜出后才写叙事；禁止因"另一个候选的故事我更早想到/更顺嘴"推翻分数更高的候选。
- **PD差异审计在标准矩阵之后**：对有月/日级可靠日期的事件，先保留完整MD/AD标准分数，
  再展示全候选的段首/段末MD/AD/PD归属、稳定性、父层语境与接力簇。不改原始总分、不建第二总分。
  若PD在候选间无区分，对排名贡献为零；若稳定区分，作为候选级专家综合的具体支持/反证，
  但单独PD差异不得确认出生分钟或越过D9/D10分辨率门。
- **段内定位（事件反推众数区，不用单点算 Dasha）**：Dasha 应期在 Lagna 段内随出生分钟连续漂移（Moon 移动 → MD/AD 边界漂几个月），❌**禁止用任何单点（段中点 / 用户原值点 / 段内取最高分）算一次 Dasha 给候选打分**——真值在段另一端时会把边界事件判进错的 AD。
    **统一方法（Case A/B 都用，不分案）**：对该候选段，对**每个事件**反推"出生时间在段内什么子窗时、该事件正好落进它该在的 MD/AD"，把各事件子窗在段内时间轴上做**区间覆盖累加、取覆盖峰值区（众数区）**——❌ 不用布尔硬求交（用户事件日期常有月级记忆误差，硬求交会被一条记错的事件清空交集 → 误杀正确 Lagna）；允许个别事件落在峰值区外（那条大概率是记错的 / 边界的）。
    · **具体用 time_scan 两点法**：查该候选段的段首/段末两条 MD/AD 时间线，看该事件日期在两端各落哪个 MD/AD——两端相同=整段一致（满足或不满足）；两端不同=该事件的 MD/AD 归属在段内变了 → 在两条之间二分找到"事件正好在目标 MD/AD 边界"的出生分钟，那一侧子窗 = 该事件的满足窗。
    · **Moon 跨 Nak 先切段**：若 time_scan 在该段内标了【Moon跨Nak】→ 该段 Dasha 起始主星跳变、两点不连续 → 在跨点把段切两半，每半各用两点法，❌禁跨 Nak 求交。
    · 原值（若用户给了）：只作"这个 Lagna 座位值得优先看"的候选池提示、平权竞争，❌**不当段内测试点、不锚定**。
    ⚠️ 边界事件：任一关键事件距其 MD/AD 边界 < 3 个月 → 权重减半、两侧都复核，禁单条否决（呼应事件日期本身有月级误差）。
    ⚠️ 众数区只定"哪个 Lagna + 段内数月级子窗"；**众数区中点 ≠ 真值**，分钟级一律交 D9/D10 换座点再收，❌禁把众数区中点当精确出生时间（假精度）。

对扫描表中的每个**Lagna区间**，用多候选评分表做结构化比较（候选≥2时横向扩展，不止A/B）：

```
┌──────────────────────────────────────────────────────┐
│          Lagna A vs Lagna B 结构化对比                 │
├─────────────┬────────────────┬────────────────────────┤
│ 维度        │ Lagna A [星座]  │ Lagna B [星座]          │
├─────────────┼────────────────┼────────────────────────┤
│ L1(命主)    │ [行星+角色]     │ [行星+角色]             │
│ L7(婚姻)    │ [行星+角色]     │ [行星+角色]             │
│ L10(事业)   │ [行星+角色]     │ [行星+角色]             │
│ L4(家庭)    │ [行星+角色]     │ [行星+角色]             │
├─────────────┼────────────────┼────────────────────────┤
│ 纹理差异    │ [欺骗性风险?]   │ [高压红利?]             │
│ 燃烧/陷落   │ [哪颗星受影响]  │ [哪颗星受影响]          │
├─────────────┼────────────────┼────────────────────────┤
│ 腿一·事实1  │ [预登记预期→✅/❌/淘汰] │ [同左]          │
│ 腿一·事实2  │ [只列候选间变化的]│ [同左]                │
├─────────────┼────────────────┼────────────────────────┤
│ 腿二·事件1  │ [匹配度+说明]   │ [匹配度+说明]           │
│ 腿二·事件2  │ [匹配度+说明]   │ [匹配度+说明]           │
│ 腿二·事件3  │ [匹配度+说明]   │ [匹配度+说明]           │
│ 腿二·事件4  │ [匹配度+说明]   │ [匹配度+说明]           │
│ 腿二·事件5  │ [匹配度+说明]   │ [匹配度+说明]           │
├─────────────┼────────────────┼────────────────────────┤
│ 合计        │ 腿一+腿二        │ 腿一+腿二              │
└─────────────┴────────────────┴────────────────────────┘

⚠️ 对比时注意：
  纹理差异可能解释匹配差异——
    如Lagna A的L7=Jupiter(Faithful)，Lagna B的L7=Saturn(Trader)
    用户婚姻延迟 → Lagna B的Saturn(Trader+凶星)更合理
  燃烧/陷落的行星在其Dasha期间事件可能弱化或走反常路径——
    如果某事件在Lagna A的匹配是❌但相关星陷落 → 可能是反常表达，不直接否定
  ⚠️ 但纹理只能解释"匹配度的细微差异"，❌ 不得用作给劣势候选强行找补、抹平硬证据缺口的兜底；某候选某事件是 ❌（硬缺失），不能用"纹理可解释"消化掉。

⚠️ 硬证据规则（反软话术搪塞）：
  带"意外/突变/反常/出乎意料/系列突破/第一个/转得快"方向词的事件 = 硬证据，
  必须正面计给突破/开创型候选（Aries/Mars/H8 剧变）；
  ❌ 禁止用"内向/务实/低调/稳扎稳打"软话术把它对冲或吸收成稳定型候选（如 Taurus）。
  自检：要用"性格本来就这样"让某反证融进当前结论前先停——这条带方向词吗？带=硬证据，必须正面计分。

⚠️ 刻板印象禁令（反潜意识加权）：
  ❌ "好学生/乖/自律=某座"（自律可以是 Saturn 压力/Mars 拼劲/Virgo 完美，禁默认归座）
  ❌ "不乖/突击=某座"；❌ 把"听起来更稳重/更体面"的候选无意识加分。
  自检：遮住候选星座名、只看"事件↔宫位/Karaka 硬对应"，总分排序会变吗？会变=刻板印象加权，重打。

→ **候选裁决定序（固定顺序，防噪声过拟合）**：
  0. **腿一淘汰**：过「淘汰三门槛」（见主纲）的候选先出局，优先于一切；Dasha 不得复活。
  1. **硬缺失出局**：某候选下某事件"落宫/宫主/drishti/Karaka 四层全 0 命中"(结构性缺失、非子窗问题) → 结构出局，优先于一切分数比较。
     ⚠️ **判"结构性"要按两点法查整段、非单子窗**：active MD/AD 主星随出生分钟在段内漂移，某一个子窗四层全 0 可能只是"该子窗 active 的 AD 不对"、非真结构缺失。**须按两点法(含 Moon 跨 Nak 切段)在整段所有可能 active 的 MD/AD 下四层皆 0，才判结构出局**；整段内任一子窗有任一层命中 = 非硬缺失、不得出局。
  2. **覆盖事件数**：众数区峰值能同时覆盖的事件条数，越多越好
  3. **评分矩阵合计**（腿一 ✅ 计数、❌ 扣分 + 腿二 ✅✅/✅ 计数；两腿等权；只计变化字段；同源去重；泛画像/自我感不直接计分）
  4. 交集/子窗宽度只作最后 tie-break——❌ "子窗最紧"不得凌驾评分总分（记错日期的噪声反会让错误候选子窗更紧）
→ 合计差 ≥2 → 采用高分候选；<2 → 出题（「每层统一流程」第 4 步），有效题计入腿一后重判
→ ⚠️ **欠定声明（禁强选）**：**判据 = 两腿合计差 <2、出题后仍 <2、且没有新角度可出**（**D1/D9/D10 各层同理**，chimiao 的 D9 层 C1/C2 平局正是这种）。→ **声明"当前欠定"**，给**当前最佳估计 + 显式"欠定/低置信"标注**，❌ 禁卡住不给结论；❌ 禁止用"子窗最紧"或对照后才想到的漂亮结构硬选一个当确定结论（假确定）。外部锚（出生手环/医院记录/出生证）与 Step 5 盲审都是可选：用户有就用、照常计入后重判，没有不卡。**门槛（防滥触发）**：合计有明确差（≥2）就**不算欠定、照常定盘**；差 <2 但还有新角度可出题 → 先出题，不急着判欠定。
```

推理过程（写在聊天框中让用户看到）：
```
  "测试区间: +5 ~ +18分钟（Lagna=Gemini）
   → 新宫主表: L7=Jupiter, L10=Jupiter...
   → 事件1(结婚): Jupiter大运 → L7=Jupiter → ✅✅
   → 事件2(创业): Venus大运 → L5=Venus → ✅✅
   → 匹配度: 5/5

   vs 原始时间（Lagna=Taurus）:
   → 匹配度: 3/5

   结论: 出生时间应在 +5~+18分钟区间"
```

**精确定位（在最佳区间内进一步缩小；D9→D10→D4/D5 逐级两边相夹）**：
```
如果D9变化点在区间内：
  → 用D9匹配进一步定位（D9 也必须出"候选×证据"评分表，不许只凭叙事说"哪个更像"）
  → 找到D9也最匹配的子区间
  → D9 级精度: 约 ±10 分钟（单 D9 换座点约 13 分钟宽；再叠 D10 才到 ±5，见渐进阶梯）
```
⚠️ **精调层的 Dasha 也走两点法、禁子段中点（同 3c，别在精调阶段把病捡回来）**：
   D9/D10/D4/D5 用分盘换座点分子区间时——事件的 MD/AD 归属**沿用 D1 层两点法已定的**（子区间很窄、Dasha 漂移小，通常不变）；
   ❌ 禁止对某个 D9/D10 子区间取中点重算一次 Dasha 当真值；
   若某子区间恰好跨了某事件的 AD 边界 → 对该子区间**重跑 time_scan(小 --range)取两点 Dasha 复核**，不靠中点。
   精调层主要靠**分盘结构**（D9灵魂/D10事业/D4财产/D5权力的 Lagna/宫主对事件与特质）区分候选，不是靠在子段中点重算 Dasha。
⚠️ **MD/AD 相同就不先查 Dasha**：精调候选间只差几十秒到十几分钟，MD/AD 归属通常不变 → Dasha 对这类边界零区分，**默认不查**；只在 a) 两点复核显示某事件的 MD/AD 归属在候选间变了，或 b) 有**日精度**事件且其 PD 边界确在候选间移动时才查。
   该级主要靠**腿一 × 分盘变化字段**（D9 对婚育、相识方式、配偶职业：D9 Lagna/7宫/7主/Venus/DK；D10 对职业、职位权责、专业：D10 Lagna/10宫/10主/Sun/Saturn/AmK），同样预登记、只计变化字段、同源去重；腿一差 <2 且满足上面 a)/b) 才查 Dasha；合计仍 <2 → 出题（「每层统一流程」第 4 步）。

### 反证强制重检（贯穿 3c–3d，每条新信息进来必跑，禁止打发）

⚠️ 铁律：每当用户补充新信息（新事件/新性格/新来源/纠正旧说法），不许只问"它符不符合当前结论"，必须问"它会不会**推翻**当前结论"。校准最大的失败模式是：选定领先候选后，对反证一律用"单一事件不足以推翻全面领先"打发，死不回头。

**新信息三问**（每条写进聊天框）：
  问1 归属：指向哪个候选？支持当前盘还是某个被淘汰候选？
  问2 计分资格：腿一（不带日期的事实与特质——预登记时写得出"某候选下不成立"、且对应字段在候选间变化，规则须对全部候选施用）/ 腿二（带日期事件×Dasha；带"意外/突变/反常"方向词的按上面硬证据规则正面计）/ 不直接计分（泛画像、自我感、关系好坏、氛围 → 记作出题素材）？
  问3 翻转：若成立要换盘吗？加进 3c 评分矩阵，重算总分，看排序变没变。

❌ 禁止用"单一事件不足以推翻全面领先"打发硬反证。一条硬信号（如 Jupiter D9 落 H8 对候选A是 ✅✅✅）必须回 3c 评分表重算。「不足以推翻」只有在**已纳入重算、且重算后排序确实没变**时才能说，且必须附重算后具体分差；未重算就说 = 违规。

⚠️ 复检范围（防"锁死后层内自洽"）：新信息触发的重算**不只在当前锁定段内**，必须回 3c 全候选矩阵——**含被淘汰的其他 Lagna 候选段**，对它们补 drishti + 精确测试点重算（只补算新增事件，不重跑历史）。任一被淘汰候选重算后追到当前锁定段 **3 分以内**（<2 翻转阈值 + 1 缓冲）→ 触发 D1 层复检重启，从 3c 全矩阵重开。

**输出**（每轮新信息后写聊天框）：
```
反证检查：新信息[X] → 指向候选[A/B]，[腿一/腿二/不计分·出题素材]
  → [已纳入3c重算 / 暂存待出题] → 重算后 候选A[分] vs B[分]
  → [翻转改判A / 未变，B领先N分，理由…]
```
⚠️ 凡写"未变"必须给出重算后具体分差，禁止只写"不足以推翻"。

⚠️ 来源更正联动（任何阶段，含校准完成后）：用户提供"出生时间来源"新信息（如事后才说"是医院时间""家人当场看表""身份证抄的"）：
   → 视为**强先验**，回 Step 0 按新来源重定误差方向/区间，触发全流程重估（权重高于普通新事件）
   → 但来源**不是 ground truth**：医院时间也可能偏（护士补记/凑整/看表滞后），不硬覆盖事件结论
   → 事件匹配稳定地与来源冲突时（如事件强指某时、来源指另一时）→ **标注冲突**（可能记录时间本身偏），
      呈现两种可能+各自证据，而非无条件作废改判到来源窗口
   （对比：普通新事件走上文"复检不必翻转"；来源信号触发重估，但仍受事件检验，不盲从）

### 3d. Nakshatra边界校验（辅助确认）

在D9精调完成后，检查最终Lagna度数是否落在Nakshatra边界附近。

```
Nakshatra边界：每13°20'（即每个星座内 0°00', 13°20', 26°40'）

1. 计算Lagna度数距最近Nakshatra边界的距离
2. 距离 > 2° → Nakshatra无争议，跳过此步骤
3. 距离 ≤ 2°（本质=一个边界二选一）→ 走「每层统一流程」，❌ 禁止凭特质印象直接拍板：

   第一步 · 先用两腿已有证据区分（不问用户）：
     · 腿二 Dasha：Vimsottari 按 **Moon** 的 Nakshatra 起算，Lagna 跨 Nakshatra 边界本身不改 Dasha。只有 time_scan 在两侧间标了【Moon跨Nak】、或某事件的 MD/AD 归属在两侧不同，才用**已采集的带日期事件**比落点；否则跳过 Dasha（两侧只差几分钟，零区分）。
     · 腿一：Nakshatra 边界同时是 D9 换座点 → 沿用 D9 精调层的腿一对照结果。
     合计差 ≥2 → **直接定，不问用户**。
   第二步 · 分不出 → 出题（`resources/calibration_quiz.md`）：把两侧 Nakshatra 可区分的特质做成成组 A/B/0，作答前锁定映射——
     · ⚠️ 反巴纳姆自检：对调两组描述用户还选同一个吗？两组不可区分/都像 → 撤题。
     · 有效题每题 1 分计入腿一，选 0 或答不上不计；合计 ≥2 → 定。
     · ❌ 禁对照后改映射、❌ 禁拿单题倾向写成"confirmed"。
   第三步 · 仍分不出且没有新角度 → 保持 D9 定位结果作最佳估计，把该边界标注为**欠定/低置信**；外部锚可选。
```

⚠️ 注意：
- 此步骤纯粹是辅助确认，不改变D9精调的核心逻辑
- Nakshatra特质描述限3条，用日常语言，不用术语
- 每个Nakshatra对应的时间偏向必须标注清楚

---

## Step 4: 输出结论

**⚠️ 首先判定情况A还是情况B：**
```
情况A（无需重算）= 全部满足：
  0. ⚠️ D9（及用户选择的后续阶梯）**已实际执行并收敛**——❌ 5/5 事件匹配但零精调**不算情况A**（那只锁了 Lagna 星座、没到分钟级）
  1. 推荐时间与原始时间偏移 ≤ 5分钟
  2. D9 Lagna未变化
  3. Lagna星座未变化

情况B（必须重算）= 任一成立：
  1. 推荐时间与原始时间偏移 > 5分钟
  2. D9 Lagna发生变化
  3. Lagna星座发生变化

⚠️ D9精调后的推荐时间也算！
   例：原01:30，D9精调后推荐01:45 → 偏移15分钟 → 情况B
```

### 情况A: 时间确认正确

```
✅ 时间校准完成

结论：您的出生时间 [HH:MM] 经过 [N] 个事件验证，
匹配度 [M/N]，无需调整。
时间精度：从 [±X分钟] 到 **[±实际达到的精度]**（回填实际跑到的阶梯层级对应精度——❌ 别写死 ±5，没跑 D10 就到不了 ±5）。
```

→ 更新structured_data.md中的"时间精度"字段
→ ⚠️ 同时写入"时间可信度"标签（❌ 别默认吃 reader 的 blanket 高）：D9 已收敛→高；仅锚定到 Lagna 星座级 / 用户止于粗级→中（D10/D5/D4 引用留余地）；欠定（最佳估计+低置信）→中或低 + 标注"时间仍未定"。下游 core 按此标签 gate 验前事复盘/免责声明。
→ 可以直接建议进入vedic-core

### ⚠️ 来源偏差回顾（校准完成后必做——向早平移在此落地，只解释不裁决）

校准结果定了之后（由事件众数区 + D9/D10 已裁决完），回顾报值与真值的差，仅作**结果解释**：
- 结果比报值**偏早** → 与"家人听哭看表 / 断脐后登记 = 报值系统性偏晚"方向一致 → 来源假设成立，可写"时间较报值早 X 分钟，与[医院登记/家人看表]的滞后偏差相符"。
- 结果比报值**偏晚 / 明显偏离** → 来源假设不成立 → 如实标注"报值可能记录错误 / 凑整 / 记错"，不硬圆到向早窗口。
- 结果与报值**基本一致** → 报值本就准确，写"原时间经校准验证准确"。❌ 禁写"与'报值偏晚/向早'先验对立/相悖"——向早平移是**弱先验、非基准**；原值验证准确时它只是**不适用**，不存在"对立"（把弱先验当成结果要调和的基准 = 反偏误纪律要防的，见本文件"向早平移是待验证先验、不是结论"）。
❌ 这一步是解释、不是校准依据；向早平移**不参与**上面的事件裁决。

### 情况B: 需要调整时间

**⚠️ 情况B铁规：**
```
❌ 禁止在时间调整后直接建议"进入core分析"（必须先重算数据）
❌ 禁止用旧structured_data继续分析

必须的顺序：
  1. 用新时间调 calc engine → calculate_full_chart(新时间)
  2. 重写 structured_data.md（Dasha/分盘/过运全部更新）
  3. 用新Dasha重新匹配事件（确认匹配度不降）
  4. 才能进core

⚠️ Dasha会随时间变化！Moon度数变了→Dasha起算点变了→所有小运日期偏移
  必须用calc重算，不能沿用旧值。
```

写入 `rectification_report.md`（报告含关键变化表+事件对比+推理过程+操作步骤）。

⚠️ **必须同时写入/更新 `user_context.md`**（与 rectification_report.md 并列的必写产物，不存在则创建）：把 Step3c 统一证据集的两腿——**腿一事实与特质**（兄弟姐妹/父母/婚育/怀孕方式/相识方式/配偶职业/职位/专业/病种/出国，以及家庭氛围、性格等出题素材）与**腿二带日期事件**（逐条+Dasha 对照），连同出题的题目、锁定映射与用户作答——按**事实项**落盘（不是评分矩阵、不是叙事标签）。这些校准阶段采集的信息此前无写入落点、用完即弃——本步补齐。写完回读确认。

聊天框输出：
```
📐 时间校准完成！

您的出生时间建议调整为 [HH:MM]（原[HH:MM]）。

✅ 已用新时间重新计算全部数据（Dasha/分盘/过运），structured_data.md 已更新。

下一步：
  a) 直接进入vedic-core分析（已用calc engine重算Shadbala）
  b) 出几道盲审问题验证校准结果（推荐）
  c) 用新时间 [HH:MM] 重排 JHora 发来新 PDF 补充最精确 Shadbala（可选，推荐）
     ⚠️ 旧 PDF 的 Shadbala 基于原始时间，校准后无效，请勿复用

详细报告见 rectification_report.md。
```

---

## Step 5: 盘外验证（Out-of-Sample Validation）（可选、推荐）

**校准完成后，提示用户是否需要额外验证。** 临界盘、欠定盘同样是可选：用户选做就做，不选不卡结论（2026-10-10 删去原"临界/欠定盘必做"一条）。

```
"✅ 校准完成。是否需要额外验证？
  a) 出几道盲审问题，验证校准结果（推荐）
  b) 直接进入分析"
```

### 模式A：盲审推断验证

**用户选了 a) 出盲审题后，必须套用 vedic-reader 的「验前事构造 SOP」完整规范（不是随口出两句"同 reader 逻辑"就算）。** 关键规范内联如下，逐条照做：

```
1. **目标 5 条**陈述式验前事（❌ 别因偷懒只出 2-3 条）；但**信号不足时按所引 SOP 的替补机制处理，穷尽 A-H 仍不足可诚实减至 3 条——绝不凑恒真**（临界/欠定盘硬信号最少，硬凑第 4、5 条恒真反而稀释盲审）。陈述式 = 直接说出推断让用户判准/不准，
   ❌ 禁止用提问或诱导式（"你是不是…？"会污染验证）。
2. 强信号优先：选推导链短、数据支撑强、用户能秒答"准/不准"的结构性事实。
   候选池(按历史命中率)：父母/家庭、教育层次、事业转折、婚姻状态等高命中区优先。
   ❌ 永久禁止：身体标记(命中8%)、疾病预测(命中0%)、性格/特质描述(不可证伪)。
3. 构造过程必须完整展示在聊天框（强信号筛选 → 宫位效率 → 陈述措辞），
   ❌ 不许只在内部想、直接甩5句结论。
4. rectifier 特有约束：❌ 禁止基于已用的5个校准事件反推（那是循环论证）。
   盲审必须针对【未覆盖领域】——校准用了事业 → 盲审就出感情/家庭方向。
5. 记命中率：命中率高 → 校准可信度提升；
   低 → 标注"盘外验证未达标"，不阻塞进入分析；
   ⚠️ 但盲审不匹配项是带日期的硬反证：若用户确认这些是真实偏差，
   须把它们回 3c 全候选矩阵按【反证强制重检】重算（见 Step 3c 反证强制重检），
   不得仅标注了事——"死不回头"是校准最大失败模式，Step 5 收到的反证同样适用。
```

**完整细则见 `resources/pre_validation_sop.md`**（候选池全表、四通道分析、P1/P1.3/P5 工具箱、构造SOP、输出模板）——出盲审题前必读。

### 模式B：时间线交叉验证

如用户愿意提供更多信息，可收集未覆盖领域的时间线做Dasha匹配：
```
1. 从校准用的5个事件中找出未覆盖的领域（至少2个）
2. 向用户收集该领域的客观时间线
3. 用校准后的盘做Dasha匹配（同Step 3a标准）
4. ≥70%匹配 → ✅ 通过 | 50-69% → ⚠️ 存疑 | <50% → ❌ 建议追加事件

⚠️ 模式B计分口径（防基础率虚高）：
  ① 只有✅✅和✅计入70%的分子，⚠️弱匹配不计
  ② "角色匹配"属泛信号，不得单独计为一条命中——
     必须与宫主(✅✅通道)或落宫/照射/Karaka(✅通道)之一同时成立才计✅
  ③ 对照组自检：抽1-2条事件在校准前的旧盘上按同一标准打分，
     若旧盘匹配率与新盘相当 → 输出"验证不具区分度"而非"✅通过"
```

---

## 关键原则

1. **借力calc**：改完时间直接调calc engine重算全部数据，用户不需要重新排盘
2. **逻辑透明**：推理过程写在聊天框，让用户看到为什么
3. **不过度校准**：5/5 匹配即**确认 Lagna 星座正确**（不为换座去无意义重扫）；但"确认 Lagna"≠"到分钟级"——分钟精度仍按阶梯 D9/D10 精调（除非用户说够了），❌ 别把 5/5 当分钟级终点
4. **扫描范围自适应**：时间精度差→扫大范围，精度好→扫小范围
5. **UTC转换**：time_scan.py 内部用 UTC；输入传本地时间（`--local-date/--local-time`），表头同时给出 UTC 与本地，展示给用户一律用本地时间
6. **可追加事件**：如果5个事件不够区分，可以要求用户追加2-3个
7. **Dasha随时间变**：改时间后必须用calc重算Dasha，不能沿用旧值
8. **渐进式校准**：D9→D10→D4/D5，让用户选择是否继续深入
