# Prompt / Skill P1、P2 重新评估（P0 后现状）

评估日期：2026-07-11
评估对象：当前 Main Prompt、`booking-desk-event` Skill、全部生产 references、README、P0 fixtures/validator、开发交接 MD/Excel 与 ADR-001。
评估性质：只读复核；本报告没有修改生产规则。

## 1. 结论先说

旧报告中的“12 组 P1 + 8 组 P2”不能原样继续使用，因为 P0 已解决一部分问题，也让一部分旧问题合并或改了性质。

按当前文件去重和重新定级后，建议形成：

- **P1：12 组**。数字碰巧仍是 12，但成员已经变化：有旧项解决、合并或降级，也有 P0 后新暴露的 package、adapter 和同卡解阻缺口。这些问题会让同一输入走不同事件/卡型、产生不同数量的事件、让严格消费者接收到不兼容结构，或让开发没有唯一权威映射。
- **P2：8 组**。数字也碰巧仍是 8，但同样不是原来的 8 项；这些问题主要集中在较窄的领域语义、示例、组合场景和测试覆盖，仍可能判错，但通常不是入口契约立即失效。
- **已解决的旧问题：2 个明确结论**：旧 P1-6 的 Allotment/Parent 边界已解决；旧 P2-3 的 filename-only Voucher 分流已解决。不过 Voucher 又暴露出一个相邻的新 P1 冲突，不能据此认为 Voucher 全部完成。
- **P3/文档卫生：1 项**：测试仍引用个人桌面绝对路径，不是生产业务冲突，但会破坏测试可移植性。

最需要先修的不是所有 P1 一起铺开，而是下面四项：

1. 42 条 adapter 路由没有生产级单一权威源，当前只完整存在于“派生交接件”。
2. Fix Charge 的动作与 Schema 没闭合。
3. Preflight/系统状态的两层门控与同卡解阻模型没有闭合。
4. Rooming List 专项 reference 仍能生产现行目录禁止的 `Note`。

## 2. 旧 20 项如何变化

| 旧编号 | 旧问题 | 当前结论 | 当前归属 |
| --- | --- | --- | --- |
| 旧 P1-1 | 历史查询 gate 太窄 | 仍存在 | 新 P1-6 |
| 旧 P1-2 | 日期规则适用范围不一致 | 仍存在 | 新 P1-5 |
| 旧 P1-3 | Fix Charge 触发/Schema 不闭合 | 仍完整存在 | 新 P1-1 |
| 旧 P1-4 | Update / Trace 重叠 | 大部分缓解，但剩余仍会直接改变 event type | 新 P1-12（靠后处理） |
| 旧 P1-5 | Update / Manual RateCode 重叠 | 仍存在 | 新 P1-4 |
| 旧 P1-6 | Allotment 部分释放/Parent Cancel | 已由 ADR-001 解决 | 移除 |
| 旧 P1-7 | `extraction_warnings` 阻塞语义 | 部分解决，剩余并入公共 Schema | 新 P1-7 |
| 旧 P1-8 | NMR 事件模型 | 九字段已解决，目标候选模型并入公共 Schema | 新 P1-7 |
| 旧 P1-9 | source/event requiredness 两版本 | event 已解决，source 示例仍残留 | 新 P2-2 |
| 旧 P1-10 | 根数组/locator 无 Schema | 仍存在 | 新 P1-7 |
| 旧 P1-11 | Invoice/Trace/payment 措辞 | Trace 主体已修，Invoice/payment 仍有冲突 | 新 P1-2 |
| 旧 P1-12 | Preflight 所有权不清 | 仍存在，并发现非字段阻塞无法稳定解阻 | 新 P1-3 |
| 旧 P2-1 | TA Recorder 可选/必选 | 仍存在，属于派生条件歧义 | 新 P2-1 |
| 旧 P2-2 | Rooming List Note/Trace | 仍存在，且违反 P0 active/legacy 目录 | 新 P1-8 |
| 旧 P2-3 | Voucher filename-only | 原冲突已解决；相邻的“明确卡型但文件对象缺失”仍冲突 | 新 P1-9 |
| 旧 P2-4 | HNM/Honeymoon 双重语义 | 仍存在 | 新 P2-3 |
| 旧 P2-5 | Rate Code 金额未标渠道 | 仍存在 | 新 P2-4 |
| 旧 P2-6 | Trace 日期无依据补全年月 | 仍存在且测试固化错误期望 | 新 P2-5 |
| 旧 P2-7 | Amend Group Code + 普通修改 | 通用拆意图规则有所帮助，但组合/目标绑定未定义 | 新 P2-6 |
| 旧 P2-8 | 测试治理 | P0 有了可执行测试，但 P1/P2 和部分 P0 语义仍无有效断言 | 新 P2-8；绝对路径另列 P3 |

本轮还新增发现：42 条 adapter 三元组没有生产级机器可读权威源（新 P1-10）；Main→Skill 只冻结 candidate item、没有冻结完整 package（新 P1-11）；FIT/Group 的“通常按房数”没有冲突优先级（新 P2-7）。

## 3. 当前 P1：12 组

### P1-1：Fix Charge 的触发、动作和输出 Schema 没闭合

**当前证据**

- `references/52-fix-charge.md:9-15` 只允许复合单价/附加费组件触发。
- `references/11-update-booking.md:75-77` 和 `52-fix-charge.md:59` 又要求支持 add、update、cancel。
- `52-fix-charge.md:41` 仍含 `create_or_update_fix_charge / TBD`。
- `52-fix-charge.md:46` 的 `operation_type` 只能表达 `create_or_update_fix_charge`，不能表达 cancel。

**会造成什么影响**

同一条明确的 Fix Charge 维护请求可能完全不触发，也可能触发后无法生成下游可消费的动作值。`TBD` 进入生产 payload 时，严格 Schema 不能接受，宽松实现则会各自解释。

**例子**

邮件：`Please remove the existing fixed charge from reservation 344055.`

- 没有 `2000+500` 之类复合价格，所以按触发规则它不是 Fix Charge。
- 但 Update reference 明确说 cancel Fix Charge 是支持动作。
- 即使识别出来，当前 `create_or_update_fix_charge` 也表达不了 `cancel`。

**建议**

冻结 `operation=add|update|cancel`；允许明确的维护动词触发，不再只依赖复合金额；删除 `TBD` 和混合工具名。工具调用名称应由下游能力注册表维护，不要作为未决枚举塞进业务事件。

### P1-2：Invoice 与 payment 的前置措辞仍会误导 Main/Skill 路由

**当前证据**

- `prompts/main_agent_prompt.md:5` 仍笼统写“不要判断 … Invoice 或 Receipt”。
- `SKILL.md:16` 仍笼统写“不生成 Invoice 或 Receipt”。
- `00-output-contract.md:185-202` 却把 `Invoice Generation`、`Invoice Received`、`Payment Notice` 列为 active event。
- `18-invoice.md:22-28` 真正禁止的是生成实际文件、确认付款和执行会计动作。
- Main `:60` 仍把没有限定词的 `payment information` 列为 Trace 信号；详细 Trace 规则才补充“已确定、非审批、非凭证、非 Notice/Invoice”。

**会造成什么影响**

模型可能在第一层就把正式支持的 Invoice 邮件排除，或者把付款政策询问错放成 Trace 粗候选。

**例子**

- `Please issue a proforma invoice.` 可能因“不要判断 Invoice”走 S10。
- `Can the balance be paid on arrival?` 可能因早期广义 `payment information` 被当成 Trace；它其实是当前不支持的付款政策审批询问。

**建议**

统一改成：“可以识别 Invoice/Payment 业务候选，但不得生成实际 Invoice/Receipt 文件、确认到账或执行会计动作。”Main 所有 `payment information` 文案统一限定为“已确定、非审批、非凭证、非 Payment Notice/Invoice”。

### P1-3：Preflight 与早期系统状态门控重复，非字段型复核又没有稳定解阻方式

**当前证据**

- README `:22`、Main `:304` 和开发交接 `:258` 都把正式 Case/Preflight/去重/锁校验交给信息系统。
- `SKILL.md:156`、`10-new-booking.md:37,67`、`11-update-booking.md:40,84` 和 `90-manual-review.md:31` 又规定 pending task、workflow、lock、duplicate 可直接把候选切成业务 manual review。
- `90-manual-review.md:100-136` 的同卡解阻只具体定义了 `missing_fields[]` 对应 `field_overrides[]` 的字段确认路径。
- pending/lock 这类阻塞可能 `missing_fields=[]`，没有字段可以让用户填写；当前规则没有说明它应等待重查、由谁解除、是否需要用户覆盖值。
- type-unknown Fallback 也可能 `missing_fields=[]`，需要用户在 New/Update 等候选路由中作选择；现有 `field_overrides[]` 既不能表达 route selection，也不能改写不可变的原 Agent event。

**会造成什么影响**

同一封 Update 邮件仅因系统查询是否可用，就可能进入 normal 卡或 manual-review 卡；随后 manual-review 卡又可能没有可填写字段，用户看得到卡却无法完成它。

**例子**

订单修改信息全部明确，但系统里已有 pending Update task：

- 查询成功：Skill 可能输出 Update manual-review。
- 查询暂时失败：Skill 可能输出普通 Update，稍后由正式 Preflight 拦截。
- 如果已经进入 manual-review，`missing_fields=[]`，前端没有 field override 可以提交。
- 如果是“无法确定 New 还是 Update”的 Fallback，用户即使已经选了 Update，当前 resolution 也没有合法字段保存“有效路由选择”。

**建议**

优先选择单一所有者：duplicate/pending/lock 只由下游正式 Preflight 裁决，Skill 仅保留 `context_used`。如果业务坚持保留早期门控，就明确命名 `advisory_preflight`，并定义查询未执行时的稳定结果及“非字段阻塞”的解阻模型，例如系统重查通过后自动 resolved。Fallback 还需要独立的 `route_selection` resolution；它应保存在信息系统的 resolution 中，原 Agent event 继续不可变，不能强迫用户填写不存在的字段或回写 Agent payload。

### P1-4：只修改 Rate Code 时仍同时匹配 Update 和 Manual RateCode

**当前证据**

- `11-update-booking.md:11-18` 把 manual Rate Code / settlement price 纳入 Update。
- `53-manual-rate-code.md:3-16` 又说“不能作为 New/Update 内嵌时”或“只有 manual rate maintenance”时输出 Manual RateCode。
- `02-event-routing-map.md:37,49` 同时保留两条 active 路由，但没有唯一优先级。

**会造成什么影响**

同一邮件可生成 Update 卡或 Manual RateCode 卡。两张卡的 task type、subtype、字段和下游流程不同，统计也会分裂。

**例子**

`For reservation 344055, change the Rate Code to CORP1.`

这既是“修改已有订单字段”，也是“只有一项 manual rate maintenance”。

**建议**

建议冻结：明确 reservation/group 的 Rate Code 或价格字段修改一律走 Update；`Manual RateCode` 只用于不直接修改某个既有订单的独立 rate-maintenance 工作流，并补充该工作流的强触发信号和最小字段。

### P1-5：通用日期规则与 QBD/LianTai 专项规则的适用范围冲突

**当前证据**

- `54-stay-date-parsing.md:5` 把用途限定为 QBD/LianTai 表格日期。
- `10-new-booking.md:32-38`、`11-update-booking.md:34-41` 和 `00-output-contract.md:249-268` 又要求一般 New/Update 涉及日期时遵循 54。
- 当前高风险日期用例集中在供应商表格，没有普通正文/PDF 的正式反例。

**会造成什么影响**

普通 FIT 邮件、PDF 或其他供应商材料没有正式日期规则；实现可能错误套用 sheet/酒店列逻辑，也可能把完整日期无故送人工复核。

**例子**

`Arrival 12 Aug 2026, departure 14 Aug 2026.`

它没有酒店列、行程列或 sheet month/year，但 New Booking 又被要求遵循以这些证据为核心的 54。

**建议**

建立“通用 stay date”规则，定义完整日期、短日期、跨月、时区/locale 和冲突处理；54 只保留 QBD/LianTai 特例。也可以把 54 改成“通用规则 + 供应商子章节”，但测试必须同时覆盖正文、PDF 和 QBD/LianTai。

### P1-6：历史查询 gate 仍挡住必要旧值和关系证据

**当前证据**

- Main `:66-70` 只在“已有 active 粗候选且目标无法唯一绑定”时允许主动查历史。
- 同一 prompt `:71-78` 和 `01-current-history-boundary.md:23-29` 又允许历史补 amendment 旧值、parent allocation 和供应商上下文。

**会造成什么影响**

目标已经唯一，但 before/after 旧值或 parent 关系只在历史里时，Main 被 gate 禁止查询，只能输出不完整候选或不必要的人工复核。

**例子**

`Confirmation 344055, change stay to 2 nights.`

confirmation 已唯一，但旧 arrival/departure 只在历史邮件。当前 gate 因“目标已唯一”不允许查历史。

**建议**

把查询条件改成：“目标绑定不足，或该 active 候选 reference 明确要求的旧值/关系证据不足。”同时区分输入中已有的 quoted-thread evidence 和主动外部 history lookup。

### P1-7：公共候选、warning、目标歧义和 `event_role` Schema 仍不闭合

**当前证据**

- `00-output-contract.md:124-143` 固定要求 `case_candidates[]`、`extraction_warnings[]`，却没有 item schema。
- `04-main-skill-input-contract.md:43-84` 只定义了内部 `target_hints`，不能替代最终业务根的 public candidate。
- `00-output-contract.md:217-240` 的 `event_role` 只有示例值，没有 enum。
- `90-manual-review.md:20-33` 允许目标不唯一时保留已知卡型，但没有定义“一组歧义一个 event”还是“每个候选一个 event”。
- `03-current-content-completeness.md:106`、`00-output-contract.md:179-180` 仍用 warning / review / S99 的选择式措辞，没有明确“warning 只允许非阻塞质量问题”。
- `04-main-skill-input-contract.md:84` 要求最终 event 使用 `context_used.main_candidate_ids[]` 记录 provenance，但现有 golden event 常用空 `context_used`，输出契约也没有把该子字段设为条件必填。
- relationship 字段只给了 prose 约束，没有统一 item/引用 Schema；通用根校验不会拒绝 dangling index 或错误 event type。

**会造成什么影响**

不同实现会自行发明数组 item、关联键和去重规则；两个候选目标可能生成一张或两张人工卡；warning 也可能被误当成终局路径。

**例子**

邮件只写 `John Smith, arrival 15 Aug`，历史找到 `R100`、`R200` 两个候选：

- 实现 A 输出一张 Update manual-review，四个 case key 全 null。
- 实现 B 输出两张 Update manual-review，看起来像两项真实修改。
- 实现 C 私自在 `case_keys` 增加 `guest_name`。

另一个例子：Update 关键信息完整，但附件第二页无关页脚 OCR 失败；一个实现 normal + warning，另一个实现整卡人工复核。

**建议**

补一份正式公共输出 Schema：

- `case_candidates[]`：candidate ID、`target_locator`、四键 canonical candidates、evidence refs、related event index。
- `extraction_warnings[]`：稳定 code、证据位置、related event index，并明确其不能单独承接阻塞问题；阻塞入口走 S99，阻塞已知卡型必需字段走业务复核。
- 固定“一项 ambiguity cluster 一个 review event”，候选只表示候选，不能变成多项真实事件。
- 冻结 `event_role` enum 和 relationship index 类型/去重规则。
- 明确 `context_used.main_candidate_ids[]` 在最终业务 event 中的 requiredness，并校验每个 ID 来自本次 Main candidate package。

### P1-8：Rooming List 专项 reference 仍能生产目录禁止的 Note

**当前证据**

- `14-rooming-list.md:42-50` 仍写 Rooming List 可以派生 Note。
- `17-ta-recorder-note.md:7-10,41-50` 仍把 Note 列为事件并提供 payer code、charge code、breakfast、note text 等 producer。
- `00-output-contract.md:204-209`、`02-event-routing-map.md:51-56` 和 ADR-001 明确 `Note` 只能读历史，当前 producer 必须为 0。
- 开发交接要求每个已确认 target 派生 TA Recorder，并给 Note 0 条合法三元组。

**会造成什么影响**

同一名单可能多出 adapter 无法路由的 Note；早餐、布置等内容还可能同时生成 Note 和 Trace。

**例子**

workbook 的备注写 `Breakfast for 20; honeymoon setup`。按旧专项 reference 可能生成 Note；按 Trace 规则应生成 meal/room_setup Trace；按现行目录 Note 又必须被拒绝。相同内容因此可能重复，或在 adapter 层丢失。

**建议**

删除 `14/17` 中的当前 Note producer，并把 `17-ta-recorder-note.md` 改成 TA Recorder-only 或将 Note 章节明确移入 legacy reader/migration。breakfast/meal/setup 等开放文本走 Trace；当前不支持的 PMS 维护或审批内容走 `unhandled_current_intents`。TA Recorder 的“必选/可选”问题单列为 P2-1，不与非法 event producer 混为一项。

### P1-9：Voucher 的 filename-only 已解决，但“明确卡型、文件对象缺失”仍有硬冲突

**当前证据**

- `13-voucher-payment.md:43-57,100-111` 已正确区分被动 filename-only、已知卡型但附件缺失/不可读、type-unknown 和方向未知。
- 但 `SKILL.md:97` 仍绝对写“Voucher 必须有当前图片、PDF 或文件证据”。
- 专项 reference `:55` 则允许 current 正文已经明确 `Voucher Received` 或 `Payment Evidence`，只是必要附件缺失/无法取得时，保留已知业务卡并进入 manual review。

**会造成什么影响**

正文明确要求处理本次 Voucher、但上传过程中附件对象丢失时，一个实现会输出 Voucher manual-review，另一个会因硬边界拒绝产生事件并走 S10/S99。

**例子**

- 只有文件名 `voucher_HD123.pdf`，无文件对象、无明确当前处理语义：S10。这一条已经清楚。
- 正文：`Please process the attached CREDIT VOUCHER for HD123`，但附件上传丢失：专项 reference 要保留 Voucher 卡；Skill 硬边界说没有文件证据不能生成。

**建议**

把“normal Voucher 必须有真实文件证据”和“明确卡型但证据丢失时允许 type-known review”分开写。保持 filename-only 的 S10 结论，不要重新打开旧冲突。

### P1-10：42 条 adapter 路由没有生产级单一权威源

**当前证据**

- 开发交接 MD `:8` 明确自称生产契约的派生件，不能覆盖上游。
- 完整 42 条 `result_type + task_type + task_subtype` 映射只出现在该交接 MD/Excel 的 `:97-140`。
- 生产 `00-output-contract.md` 只规定“保留原业务 task type/subtype”的原则，没有给出 19 个 subtype 到具体三元组字符串的完整表。
- P0 validator 的 `deriveAdapterTriplet()`（`validate_p0_contracts.mjs:353-409`）只实现 New、Update、Cancel、Cancel Allotment、Trace；其他 active event 会直接 `throw`，没有自动验证全部 42 条。
- Parent split 的 Parent event 同时具有 `cancel_object_type=group_block` 和 `relationship_type=linked_parent_release_after_child_split`；交接表中的普通 group cancel 与 linked parent cancel 两行都可命中，但生产 contract 没有冻结 adapter 判别优先级。

**会造成什么影响**

开发必须依赖一份自称“非规则源”的文档才能知道具体 task subtype；未来生产 event 字段改动时，没有单一机器可读源可以生成交接件并阻止漂移。

**例子**

`Voucher Received` 应映射到 `lian_tai_credit_voucher`，`TA RECORDER` 应映射到 `maintain_ta_recorder`。这些精确 subtype 字符串无法从当前生产 reference 唯一推导，只在交接表里完整出现。Parent event 则可能被 Adapter A 先按 object type 路由成 `cancel_group_block`，被 Adapter B 先按 relationship 路由成 `linked_parent_release_after_child_split`。

**建议**

新增生产级 `05-adapter-routing-contract`（推荐机器可读 JSON/YAML，或带可执行表的 reference），把 42 条映射和判别优先级作为唯一源；例如 Parent relationship 判别必须先于普通 cancel object 判别。开发 MD、Excel 和测试都由它生成，并完整校验 42 条唯一性、19 个业务 subtype 的 normal/manual 成对关系和禁用 legacy 事件。

### P1-11：Main→Skill 只冻结 candidate item，没有冻结完整 package

**当前证据**

- Main `:93-127` 给了素材包初始化 shape，但没有冻结各 material item、history/system context 和 unknowns 的完整类型。
- `04-main-skill-input-contract.md:73-84` 要求 `evidence_refs[].index` 必须真实指向对应 current material，却没有一份完整 package schema 可用于验证引用。
- `candidate_gate.json` 和 validator 只传入/校验 `candidate_events` 数组；没有同时传对应 attachments/tables/OCR，因此 `index=999` 也无法判断是否越界。

**会造成什么影响**

candidate item 自身合法，不代表它引用的材料存在。Skill 可能在运行时读错附件、错行或直接报 contract error；不同编排实现也会自行决定 material item shape。

**例子**

```json
{
  "candidate_id": "C1",
  "evidence_refs": [{"source": "current_attachments", "index": 999}]
}
```

如果实际 `current_attachments=[]`，这应该在调用 Skill 前失败；现有 candidate-only validator 看不到附件数组，不能拒绝它。

**建议**

把 `04-main-skill-input-contract.md` 扩成完整 package schema：冻结 source/body/material arrays、attachment/table/OCR item、history/system context、candidate events、unknowns 和错误返回；validator 必须接收整个 package，校验引用存在、索引范围、current-only 来源和 candidate provenance。

### P1-12：Update / Trace 的“修改既有备注”仍可产生不同 event type

P0 已明确主修改与 linked Trace 分开，不能把补充信息吞进 Update；但 `11-update-booking.md:5-19` 仍把“备注或其他订单细节”纳入 Update，Trace 又把 high floor、quiet room 等偏好定义为补充信息。

**会造成什么影响**

同一输入可能生成 Update、Trace 或两张重复卡。虽然场景比旧版窄，但它仍是直接的 event-type 路由漂移，因此保留为靠后的 P1，而不是只当措辞问题。

**例子**

`Please change the existing note from high floor to quiet room.`

**建议**

冻结语义边界：修改/删除一个可定位的已存字段或备注，且 before/after 清楚时走 Update；新增偏好、要求、安排或事实走 Trace，不受 `update/add note` 动词影响；同一内容不得同时作为 Update 核心字段和 Trace。

## 4. 当前 P2：8 组

### P2-1：TA Recorder 仍在“可能/通常派生”和“每个目标必须派生”之间摇摆

`14-rooming-list.md:42-50` 写 Rooming List “可能派生”，`17-ta-recorder-note.md:5` 写“通常由”，但同文件 `:21-29` 又要求每个已确认 group 派生一个 TA Recorder；开发交接和高风险清单也按必派生理解。

例子：一个 workbook 有两个已确认团号。可选解释只出 2 个 Rooming List；必选解释还要出 2 个 TA Recorder，共 4 个事件。

建议：若当前产品要求已确认 target 必派生，就统一改成“每个已确认 target 必须且只能派生一个 TA Recorder”；目标未确认时先保留 Rooming List 卡的人工确认，不提前生成无目标 TA Recorder。补事件数和关系的可执行断言。

### P2-2：Skill 的 `source_message` 示例仍比正式固定 shape 少字段

event 的 `attachments`、`file_references`、`manual_review` requiredness 已解决；只剩 `SKILL.md:118-127` 示例仅含 `source_message_id`，而 `00-output-contract.md:124-143` 要求六个 metadata key 固定存在。

例子：严格 validator 接受完整 source shape，但照抄 Skill 示例会缺 `subject/from/cc/received_at/source_channel`。

建议：把 Skill 和交接示例同步为完整 shape；不可得值用 `null` 或 `[]`。由于 00 已是明确权威、剩余主要是示例误导，降为 P2。

### P2-3：`HNM/Honeymoon` 没有区分结构化房型代码和自然语言布置要求

`50-room-type-mapping.md:9-20` 把 `HNM, Honeymoon` 默认走 DBL；`16-trace-notes.md:67-74,139-143` 又把 honeymoon 作为 room setup Trace。

例子：`Room Type: TWN; Remark: honeymoon decoration.` 正确应是 RM3 + room-setup Trace；宽泛规则可能把房型改成 DBL 或制造无谓冲突。

建议：只有已知供应商的结构化房型字段中正式 `HNM` code 才能参与房型映射；正文/备注的 honeymoon 只能作为 Trace，不能决定 PMS 房型。

### P2-4：Rate Code 金额示例仍未绑定 supplier/channel

`51-rate-code.md:9-15` 区分 QBD/LianTai，但 `:17-22` 又写无渠道的 `850/900/1000/1200 -> code`；`:24` 才补“渠道优先”。

例子：QBD 900 应是 `GRPA1-900`，LianTai 900 是 `GRP1-900`；无渠道的 `900 -> GRP1-900` 会误导模型。

建议：每个金额示例绑定 supplier/channel；渠道未知时只保留 price evidence，`rate_code=null` 并在原业务卡人工确认。

### P2-5：Trace 示例仍无依据地从 group code 补全年月

`16-trace-notes.md:55-60` 要求日期只能由可靠上下文唯一支持；`:82-100` 却仅用 `HD260510A + 12/5` 输出 `2026-05-12`。项目没有 group-code 日期 codec，`high_risk_cases.md:25` 还把该结果写成期望。

例子：只有 `HD260510A - 12/5 FULL DAY Meeting` 时，安全值应是 `service_date=null` 并保留 raw `12/5`；只有邮件住期或 sheet context 明确 2026-05 时才可补全。

建议：给示例补可靠年月证据，否则将期望改为 null。若业务确有 group-code 编码，另建供应商专属 codec，明确格式、适用范围和冲突处理。

### P2-6：Amend Group Code 与日期/房量组合的事件数量和目标绑定未定义

通用规则已要求独立 current 信号先拆分，这比旧版更好；但 `15-amend-group-code.md:24-50` 只定义 old/new 两字段和 Amend + Trace，没有定义 Amend + Update 的关系、Update 绑定旧团号还是新团号。

例子：`Change OLD123 to NEW123, move arrival to 12 May, add 2 TWN.` 可能只出 Amend，也可能出 Amend + Update，但 Update 的 key 不一致。

建议：明确输出两个相关主事件；优先用稳定 confirmation/reservation number 共同绑定。只有 group code 时，定义 before/after target 和 relationship；无法确认时保留已知 Update 卡型并进入人工确认，不能把日期/房量静默塞进 Amend context。

### P2-7：FIT / Group Block 的“通常按房数”缺少冲突优先级

`10-new-booking.md:13-18` 写“小于 5 间通常按 FIT，5 间及以上通常按 Group Block”，但没有说明显式对象词、渠道规则、团队名称和房数冲突时谁优先；`booking_object_type` 又是 adapter 三元组的 subtype 判别字段。

例子：正文明确写 `group booking` 但只有 4 间，或一个家庭 FIT 请求 5 间。两个实现可能分别只看房数或只看显式业务词，生成不同 task subtype。

建议：冻结判别优先级，例如“受支持供应商结构化对象类型/显式 group or FIT 指令 > 已知渠道规则 > 房数阈值”；冲突且 subtype 无法确定时才走 type-unknown Fallback。补 4-room explicit group、5-room explicit FIT、无显式词的 4/5-room 四组用例。

### P2-8：P0 有可执行测试，但当前绿色结果不能覆盖 P1/P2，也没有发现部分 P0 测试文字回退

**已经改善**

- 7 份 JSON fixture 和 `validate_p0_contracts.mjs` 当前运行结果为 32 checks passed、9 个负例被拒绝。

**仍有问题**

- `deriveAdapterTriplet()` 只实现 5 类 active event 分支，没有覆盖 Voucher、Payment Evidence、Rooming List、Amend Group Code、TA Recorder、Invoice、Payment Notice、Manual RateCode 的 42 路由。
- `validateBusinessRoot()` 只检查 `case_candidates`、`extraction_warnings` 是数组，不检查 item，因为生产本身也没有 item schema。
- Parent 测试对 `child_group_codes[]` 和 `related_source_event_indices[]` 分别排序后比较，不能证明二者按原顺序一一对应；交换两个 index 仍可能通过。
- 没有验证最终 event 的 `context_used.main_candidate_ids[]` provenance。
- `high_risk_cases.md:19,45,49,50` 仍把 type-known 日期、Trace 目标、Rooming List 目标和 Voucher 团号歧义写成 `Need Manual Review`，与 P0 当前“保留原业务 event + 非空 manual_review”冲突。
- P1/P2 领域场景仍主要是 Markdown，自然语言清单不会让 CI 失败。

**建议**

先修正过时的 Markdown 期望，再将本报告每一项做成正反 golden fixture。测试至少要覆盖：全部 42 路由、public root item schema、candidate provenance、关系数组按位置配对、type-known review 不回退 Fallback，以及本报告列出的领域边界。

## 5. P3：测试绝对路径

`tests/booking-desk-event/high_risk_cases.md:38` 仍引用 `/Users/chillishark/Desktop/.../53.eml`。这不会直接改变生产路由，所以不再占一个 P2 业务冲突名额；但换机器无法复现。

建议把脱敏样本放入仓库 `tests/booking-desk-event/fixtures/` 并用相对路径引用；若原始邮件不能入库，就制作最小脱敏 JSON/EML fixture。

## 6. 推荐修改顺序

建议分四批，不要一次把所有 reference 平铺修改：

1. **先封闭机器契约**：完整 42 路由单一权威源、Main→Skill 完整 package、公共 root/relationship/provenance schema、Fix Charge 和 source shape。
2. **再封闭路由边界**：Rooming List/TA/Note、Voucher 文件证据、Invoice/payment、Update/Manual RateCode。
3. **再封闭流程状态**：Preflight/advisory gate、非字段阻塞解阻、历史查询 gate。
4. **最后修领域规则与测试**：通用日期、HNM、Rate Code、Trace 日期、Amend 组合，并把每项转为可执行 fixture。

在这四批中，ADR-001 已确认的 P0 结论必须保持不变：

- 不恢复部分配额 Update 或 Allotment Maintenance producer。
- 不恢复当前 Note producer。
- type-known 字段/目标歧义保留原业务 event，不能重新 blanket Fallback。
- Parent split 继续是 Child Group New + Parent Group Cancel candidate。
- 房型不唯一继续使用同业务卡 manual-review mode，不改回普通候选或第二张卡。

## 7. 验证说明

- 本轮重新运行 `node tests/booking-desk-event/validate_p0_contracts.mjs`：32 项通过，9 个非法负例按预期拒绝。
- `.project-docs` 完整性检查通过。
- 上述通过结果只能证明现有 P0 fixture 自洽，不能证明本报告列出的 P1/P2 已关闭；原因见 P2-8。
