# 03 Skill Catalog

## 1. 定位

本文是预订部 AI 工作台的 Skill 路由索引 / 目录。

它回答的问题是：

- 当前 `body_current` 邮件事件应该路由到哪个 Skill。
- 哪些场景不能路由到某个 Skill。
- 该 Skill 第一版允许输出哪些 `result_type`。
- Main Agent 至少应准备哪些上下文。
- 路由冲突或无法安全判断时应如何兜底。

本文不写：

- 具体业务字段抽取规则。
- 完整 `ai_task_result` 输出 schema。
- PMS / Opera 写入规则。
- 任务卡 API 的真实 endpoint、鉴权、返回结构。
- 具体字段标准化、房型映射、Rate Code 规则、价格规则。

详细业务规则和输出细节应写在具体 Skill 文档中。

## 2. 第一版全局结果类型

第一版全局只使用以下结果类型：

- `normal_task`
- `manual_review`
- `informational_message`

第一版不使用：

- `exception_task`
- `no_action`

原因：

- `exception_task` 暂缓引入，避免早期异常枚举膨胀。
- `no_action` 暂不使用，避免进入 AI 工作台的 current 邮件事件被系统静默吞掉。
- 即使是 thank you、FYI、acknowledgement、仅确认收到等邮件，也应生成用户可见记录。

### 2.1 normal_task

`normal_task` 表示当前邮件事件有明确、可执行、可自动创建任务卡的业务动作。

使用要求：

- 当前动作必须来自 `body_current`。
- 必须能确认任务类型。
- 必须能确认最低溯源信息。
- 必须经过对应 Skill 的业务判断。
- Skill 不直接写数据库、不写 Opera、不直接执行真实业务动作。

### 2.2 manual_review

`manual_review` 表示当前邮件事件与业务相关，但不能安全自动处理，需要创建结构化人工复核 / 人工处理卡。

`manual_review` 不是空泛的“人工看一下”。凡允许输出 `manual_review` 的 Skill，默认必须遵守统一输出契约；如果具体 Skill 文档基于最新确认口径明确采用精简结构，以该 Skill 文档为准。

- 能确定的 `case_keys` 必须填入。
- 能确定的 subtype / object_type 应填入 `extracted_fields`。
- 能确定的业务字段应尽量填入 `extracted_fields`。
- 不能可靠确认的字段不得编造，应填 `null`、空字符串或空数组。
- 必须说明人工处理原因。
- 必须说明阻断点、缺失字段、冲突点。
- 默认应给出建议人工动作。
- 默认应给出建议人工检查的证据位置。

Catalog 不定义完整 schema，但具体 Skill 文档应至少覆盖这些语义：

- `manual_review.reason_code`
- `manual_review.visible_reason`
- `manual_review.blocking_points`
- `manual_review.missing_fields`
- `manual_review.conflicting_points`
- `manual_review.suggested_human_actions`
- `manual_review.evidence_to_check`
- `manual_review.review_record_type`

当前已确认的例外：

- S04 `voucher_received_skill` 的 `manual_review` 使用精简结构，不包含 `suggested_human_actions` 和 `evidence_to_check`。
- S05 `rooming_list_name_list_skill` 的 `manual_review` 使用精简结构，不包含 `suggested_human_actions`，但仍保留 `evidence_to_check`。

### 2.3 informational_message

`informational_message` 表示当前邮件没有可执行业务任务，但仍需要用户知晓。

适用场景包括：

- thank you
- FYI
- acknowledgement
- 仅确认收到
- 无新业务动作但有沟通价值的 current 邮件

`informational_message` 最终应对应一种轻量级用户可见卡片，例如信息提醒卡。

注意：

- `informational_message` 是 result type，不是普通业务任务。
- 如果当前邮件没有可执行业务动作，不应硬路由到 New / Update / Cancel 等业务 Skill。
- 这类邮件应由 `message_notification_skill` 输出 `informational_message`。

## 3. 统一 Tool 占位

Catalog 不为每个 Skill 设计专用任务卡创建 Tool。

统一预留：

- `suggested_tool_name: create_task_card / TBD`

`tool_purpose`：

- 根据 `result_type` 创建普通任务卡、人工复核卡、信息提醒卡或其他用户可见记录。

调用原则：

- Skill 输出 `ai_task_result` 并通过统一输出校验后，由 Main Agent、AI Runtime、Skill Orchestrator 或信息系统调用统一 Tool / API。
- Skill 能解析出的字段照实传给统一 Tool。
- Skill 解析不出的字段传 `null`、空字符串或空数组。
- 前端或信息系统可根据缺失字段提示用户补充或确认。

Catalog 只定义 Tool 方向，不定义真实 API。

统一 payload 至少应覆盖这些溯源与展示字段：

- `source_message_id`
- `source_event_index`
- `catalog_code`
- `skill_id`
- `result_type`
- `task_type`
- `case_keys`
- `visible_reason`
- `relevant_message_excerpt`
- `attachments`
- `context_used`
- `extracted_fields`
- `manual_review`
- `informational_message`
- `idempotency_key / TBD`

如某个业务 Skill 输出 `additional_operations` 或 `fix_charge_items`，这些字段也应随 `extracted_fields` 传入统一任务卡 Tool，由信息系统在后续真实业务执行阶段处理。

`must_not_call_when`：

- Skill 输出不符合统一契约。
- current 事件完全不应进入 AI 工作台记录。
- 输出内容缺少创建用户可见记录所需的最低溯源字段。

## 4. 全局路由原则

Main Agent 路由前应先做这些判断：

1. 确认业务动作是否来自 `body_current`。
2. 将 `body_thread` 仅作为 evidence context，不作为生成 `normal_task` 的来源。
   - 如果业务动作来自 `body_current`，`body_thread` 可以作为 target binding evidence，补充唯一 `group_code`、parent group、上游任务或最近相关酒店确认段；输出中必须记录 target 来源。
3. 如果一封邮件包含多个 current 业务事件，应拆成多个 `source_event_index`。
4. 如果 QBD / LianTai Excel 或 table workflow 有多个当前有效黄色 / 高亮行，必须按行拆成多个 `source_event_index`，最终一行一个 `ai_task_result`。
5. 尽量提取 `group_code`、`confirmation_number`、日期、房量、对象类型等路由线索。
6. 能提取 key 时，应查询并传入 `routing_context`。
7. 根据本 Catalog 的 `when_to_use` / `must_not_use_when` 选择 Skill。
8. 如果多个 Skill 冲突且无法安全拆分，走兜底路由生成结构化 `manual_review`。
9. 如果 current 邮件明确没有可执行业务动作但需要用户可见，走 `message_notification_skill` 生成 `informational_message`。
10. 如果无法判断 current 邮件是消息通知还是业务动作，或存在路由冲突 / current-history 边界不清，走 `exception_detection_skill` 生成 structured `manual_review`。

`body_current` 与 `body_thread` 的边界优先级高于业务关键词。

例如，历史引用里的 cancel / CXL / amendment 不应直接生成当前任务。

### 4.0 QBD / LianTai Row Split Output Validation

当 QBD / LianTai 当前有效黄色 / 高亮行数为 N 时，统一输出校验必须确认：

- 顶层 `ai_task_results.length` 等于 N，除非某些行因不可读而各自输出 structured `manual_review`。
- 每个当前有效行都有独立 `source_event_index`、独立 `case_keys`、独立 `extracted_fields.table_evidence`。
- 不得用单个 `ai_task_result.extracted_fields.source_event_count`、数组型 `case_keys.group_code`、汇总型 `highlighted_rows` 或汇总型 `room_items` 代替多个 `ai_task_results`。
- 某一行信息缺失或冲突时，只该行输出 structured `manual_review`，不得阻塞其他可安全处理的行。
- 违反本节即视为 Skill 输出不符合统一契约，Main Agent 应按 workflow 重试一次。

受控例外：

- 如果同一 current event / 同一表格行同时包含 S01 / S02 / S06 主业务动作和 Trace / Guest Request / extra bed，应生成主业务任务和 S07 linked task。
- 主业务任务先执行，S07 linked task 后执行。
- 不得把主业务任务和 S07 合并成一个 `ai_task_result`。
- 如果 `source_event_index` 只能使用整数，S07 linked task 使用新的整数 index，并通过 `parent_source_event_index`、`linked_task_group_id`、`execution_order` 表达同源关系。

### 4.1 Extra Bed / Guest Request Routing Rule

Extra bed / 加床 / `เตียงเสริม` 属于 Trace / Guest Request 类信息，不属于房型、房量或 Rate Code 判断字段。

全局规则：

- 不计入 `room_quantity`。
- 不影响 FIT / Group 判断。
- 不作为独立房型映射。
- 不单独决定 Rate Code。
- `U-เตียงเสริม` 不是 PMS 房型。
- S07 中 extra bed 固定输出 `trace_subtype=extra_bed`、`trace_text=Set Extrabed`、`notify_departments=["FO","HSK"]`、`occupancy_update=3adult`、`requires_rate_update=true`、`rate_adjustment_formula=rate_code_price / 2 * 3`。
- S07 只输出加床操作意图，不自行决定 Rate Code，不猜 `rate_code_price`，不自行计算最终房价。

路由规则：

- 如果 extra bed 与 New Booking 同一 current 事件 / 同一表格行出现，主任务走 `new_booking_skill`，同时生成 S07 linked task；先处理 S01，再处理 S07。
- 如果 extra bed 与 Update Booking 同一 current 事件 / 同一表格行出现，主任务走 `update_booking_amendment_skill`，同时生成 S07 linked task；先处理 S02，再处理 S07。
- 如果 extra bed 与 Amend Group Code 同一 current 事件 / 同一表格行出现，主任务走 `amend_group_code_skill`，同时生成 S07 linked task；先处理 S06，再处理 S07。
- 如果 current 邮件仅要求为既有订单添加、修改或取消 extra bed / 加床 / `เตียงเสริม`，走 `trace_reservation_notes_skill`。
- 如果 Cancel Booking / CXL 行中只是历史或被取消对象上的 extra bed，不默认生成 S07；除非 current 明确要求取消后仍需记录某条 note / trace。
- 不得把 extra bed 数量计入房量，也不得用于 FIT / Group 判断。

### 4.2 Fix Charge / Composite Unit Price Routing Rule

Fix Charge / 固定费用不是第一版独立任务类型。它是 New Booking 或 Update Booking 的附加收费能力。

全局规则：

- 不因为 `TWN` / `DBL` / 普通房型本身触发 Fix Charge。
- 不因为普通价格如 `2000THB`、`1800THB` 本身触发 Fix Charge。
- 当 LianTai 表格酒店说明或 current 事件价格区出现可拆分的复合单价结构，例如 `2000THB+500`、`1800THB+500`、`2000THB*2` 换行后 `+附加500*2`，才识别 Fix Charge。
- `+` 前的房费单价组件用于 Rate Code 判断；`+` 后的附加费用单价组件写入 `extracted_fields.fix_charge_items`。
- 不得把 `2000+500` 合并为 `2500` 判断 Rate Code。
- Fix Charge 金额不固定，不得用 `500` 这个数字本身作为触发条件。
- AI 不负责从该表达计算数量或总额；如表达包含 `*数量`，可作为原文证据保留，但不强制计算。

路由规则：

- 如果 Fix Charge 与 New Booking 同一 current 事件 / 同一表格行出现，主路由仍走 `new_booking_skill`。
- 如果 Fix Charge 与 Update Booking 同一 current 事件 / 同一表格行出现，主路由仍走 `update_booking_amendment_skill`，可标记 `update_fix_charge`。
- 如果 current 邮件只要求为既有订单添加、修改或取消 Fix Charge，且目标订单和动作明确，第一版可路由到 `update_booking_amendment_skill`；如果目标订单或动作不清，输出 structured `manual_review`。
- 如果没有复合单价或附加费组件，仍按既有房型 / Rate Code 规则正常处理，不因缺少 Fix Charge 输出 `manual_review`。

## 5. Catalog Entry 字段

每个 Skill 条目建议包含：

- `catalog_code`
- `skill_id`
- `skill_name`
- `task_type`
- `status`
- `supported_subtypes`
- `when_to_use`
- `must_not_use_when`
- `allowed_result_types`
- `key_context_needed`
- `input_requirements_summary`
- `conflict_or_fallback_rule`
- `tool_placeholder`

如果某个字段暂时不需要，可写 `TBD` 或说明暂不适用。

## 6. Active Skills

以下三个 Skill 是当前 active 核心业务 Skill。

### S01 New Booking Skill

`catalog_code`: `S01`

`skill_id`: `new_booking_skill`

`skill_name`: `New Booking Skill`

`task_type`: `New Booking`

`status`: `active`

`supported_subtypes`:

- `new_fit_reservation`
- `new_group_block`
- `new_allotment_control_block`

`reference_files`:

- `skill/S01_new_booking_skill/references/room_type_mapping_rules.md`
- `skill/S01_new_booking_skill/references/rate_code_rules.md`
- `references/qbd_liantai_email_table_rules.md`

说明：

- Catalog 不展开房型映射表或 Rate Code 规则。
- 当 S01 涉及房型、房型代码、Rate Code、结算价格、渠道 / 市场类别、早餐或用餐餐厅时，具体 Skill 应读取对应 reference。
- 房型代码必须来自 room type mapping reference 的唯一命中；Rate Code reference 可以引用 `pms_room_type_code`，但不能作为房型映射唯一来源。
- `ST+K:2卧1厅=1200` + `FAMILY 1` 是跨 QBD / LianTai 渠道可识别的房型表达；房型映射可命中 `SU3`，Rate Code 必须按渠道分别判断。
- 当 current 邮件、附件、发件人、主题或抽取证据显示 QBD / LianTai Excel/table workflow 时，具体 Skill 应读取 shared reference，判断高亮 / 黄色行、表格行证据和 FIT / Group / Allotment 对象路径。
- QBD / LianTai / 旅行社语境下，`AMEND + FINAL BOOKING` 不必然是 S02 Update。如果 body_current 实质是在父团下创建多个子 `group_code` 的配合房 / Allotment，并逐个给出日期、房型和房量，应按 S01 New Booking / Allotment 处理。
- 如果 extra bed / 加床 / `เตียงเสริม` 与 New Booking 同一事件或同一表格行出现，主任务仍走 S01，同时生成 S07 linked task；extra bed 不计入房量，不影响 FIT / Group，不做房型映射，不单独决定 Rate Code。
- 如果 LianTai 复合单价表达与 New Booking 同一事件或同一表格行出现，主任务仍是 New Booking；具体 Skill 应在 `extracted_fields.fix_charge_items` 中保留 Fix Charge 单价组件，并在 `additional_operations` 中标记待后续执行的 Fix Charge 操作。
- reference 无法唯一命中时，不由 Main Agent 猜测，应交给 S01 输出结构化 `manual_review` 或明确的手工价格维护任务。

`when_to_use`:

当前 `body_current` 明确提出创建新的预订对象时使用。

覆盖对象：

- FIT Reservation
- Group Block
- Allotment / Control Block 类新建控房订单
- 配合房 / 取配 / parent-to-child allocation 创建；包括 current 文本写作 `AMEND + FINAL BOOKING`，但实质是在父团下创建多个子 group code 的房量分配

`must_not_use_when`:

- 当前邮件是在修改既有订单。
- 当前邮件是在取消订单、Group Block、控房、配额、Allotment 或 Control Block。
- 当前邮件只是提交 Rooming List / Name List。
- 当前邮件只是收到 Voucher、Credit Voucher、payment slip 或 payment confirmation。
- 当前邮件只是添加 Trace、Reservation Notes 或 Guest Request。
- 当前邮件只是为既有订单添加、修改或取消 extra bed / 加床 / `เตียงเสริม`，且没有新建预订动作。
- 当前邮件只是修改 Group Code、Block Code、Block Name 或 Group Name。
- 新建预订动作只出现在 `body_thread`。
- 当前邮件只是 thank you、FYI、acknowledgement、noted、received、confirmed receipt、确认收到、转发说明、仅同步信息或无新业务动作。

`allowed_result_types`:

- `normal_task`
- `manual_review`

`must_not_result_types`:

- `exception_task`
- `no_action`
- `informational_message`

`key_context_needed`:

- `source_message_id`
- `source_event_index`
- `group_code`
- `confirmation_number`
- 房间数
- 入住 / 离店日期
- 客人姓名、团队名称或 block 名称
- supplier / sender 线索
- 当前附件摘要
- 房型原文、床型、人数、是否套房、是否家庭房等房型映射线索
- 渠道 / 市场类别、supplier、备注价格、是否含早餐、用餐餐厅、实际结算价格等 Rate Code 判断线索
- extra bed / 加床 / `เตียงเสริม` 等 Trace / Guest Request 线索
- LianTai 复合单价、附加费、Fix Charge 原文线索
- `routing_context`

`input_requirements_summary`:

Main Agent 应传入当前新建请求摘要、`body_current` 原文片段、附件摘要、已提取核心 key、路由查询结果、与新建判断直接相关的基础业务字段，以及能帮助房型映射、Rate Code 判断、Fix Charge 识别或手工结算价格维护的上下文线索。

`conflict_or_fallback_rule`:

如果当前事件明确是 New Booking，且 routing context 未发现同 key 有效订单、pending/open task、active workflow 或终止冲突，输出 `normal_task`。

如果 current 文本为 parent-to-child 配合房 / Allotment 创建，应按 child group code 拆分多个 S01 结果；父 group code 作为 `parent_group_code` evidence，不作为单个 S02 修改目标。

如果同 key 已存在已完成 / 已写入的 FIT Reservation、Group Block、Allotment / Control Block 或其他有效订单记录，不得继续创建 New Booking，应输出结构化 `manual_review`。

如果同 key 已有 pending / open task、active workflow、对象类型不清、关键信息缺失、current/history 边界不清、房型映射 reference 无法唯一命中、Rate Code reference 无法唯一命中、结算价格无法可靠确认，也输出结构化 `manual_review`。

如果 Rate Code 无可选代码但 reference 明确允许手工结算价格维护，且业务动作来自 `body_current`、routing context 不阻断、房型唯一映射、核心日期 / 房量 / 对象类型可靠、价格来自 `body_current` 或当前表格行并可可靠提取，S01 可输出 `normal_task`；输出必须包含 `rate_code=null`、`settlement_price`、`manual_settlement_price_required=true`、`manual_price_reason_code`、`price_evidence`。任一条件不满足则输出结构化 `manual_review`。

如果当前事件只是为既有订单添加、修改或取消 extra bed / 加床 / `เตียงเสริม`，不进入 S01；应路由到 `trace_reservation_notes_skill`。

如果当前事件包含 LianTai 复合单价表达，S01 应按 reference 拆分房费单价和 Fix Charge 单价；没有复合单价时，继续按既有房型 / Rate Code 规则处理。

如果当前邮件不是新建预订，而是明确的信息提醒类邮件，不进入本 Skill，应由 `message_notification_skill` 输出 `informational_message`。

`tool_placeholder`:

- `suggested_tool_name: create_task_card / TBD`
- 通过统一 Tool 创建普通 New Booking 任务卡或结构化人工复核卡。
- 如 `extracted_fields.fix_charge_items` 非空，任务卡 payload 应保留后续 `create_fix_charge / TBD` 操作信息；真实 Fix Charge Tool 只能在 New Booking 创建成功并取得订单 ID 后执行。

### S02 Update Booking / Amendment Skill

`catalog_code`: `S02`

`skill_id`: `update_booking_amendment_skill`

`skill_name`: `Update Booking / Amendment Skill`

`task_type`: `Update Booking`

`status`: `active`

`supported_subtypes`:

- `update_stay_dates`
- `update_nights`
- `update_room_type_or_quantity`
- `update_guest_count`
- `update_trace_or_guest_request`
- `update_group_block_linkage`
- `update_allotment_control_block`
- `manual_rate_code_or_settlement_price`
- `update_fix_charge`

说明：

- subtype 只用于识别修改内容、测试覆盖、任务卡展示和 payload 结构化。
- subtype 不拆成多个 Tool。
- 原 `update_pax` 命名调整为 `update_guest_count`。
- `update_group_block_linkage` 不覆盖旧 Group Code 改为新 Group Code 的 `AMEND GROUP CODE` 事件；这类事件由 S06 处理。
- `update_trace_or_guest_request` 只用于标记 Trace / Guest Request 与其他核心 Update 同一 current 事件出现时的后台线索；独立 Trace / Reservation Notes / Guest Request 任务应走 S07。

`reference_files`:

- `skill/S02_update_booking_amendment_skill/references/room_type_mapping_rules.md`
- `skill/S02_update_booking_amendment_skill/references/rate_code_rules.md`
- `references/qbd_liantai_email_table_rules.md`

说明：

- Catalog 不展开房型映射表或 Rate Code 规则。
- 当 S02 涉及房型、房型代码、Rate Code、结算价格、渠道 / 市场类别、早餐或用餐餐厅时，具体 Skill 应读取对应 reference。
- 房型代码必须来自 room type mapping reference 的唯一命中；Rate Code reference 可以引用 `pms_room_type_code`，但不能作为房型映射唯一来源。
- `ST+K:2卧1厅=1200` + `FAMILY 1` 是跨 QBD / LianTai 渠道可识别的房型表达；房型映射可命中 `SU3`，Rate Code 必须按渠道分别判断。
- 当 current 邮件、附件、发件人、主题或抽取证据显示 QBD / LianTai Excel/table workflow 时，具体 Skill 应读取 shared reference，判断高亮 / 黄色行、QBD 当前行选择、LianTai 酒店列日期、划线 before / after、AMD/CXL/CFM 状态证据和 FIT / Group 路径。
- 如果 extra bed / 加床 / `เตียงเสริม` 与 Update Booking 同一事件或同一表格行出现，主任务仍走 S02，同时生成 S07 linked task；extra bed 不计入房量、不作为房型映射、不单独决定 Rate Code。
- 如果 LianTai 复合单价表达或明确 Fix Charge 维护与 Update Booking 同一事件或同一表格行出现，可标记 `update_fix_charge`；没有复合单价或附加费组件时，继续按既有房型 / Rate Code 规则处理，不因此输出 `manual_review`。
- reference 无法唯一命中时，不由 Main Agent 猜测，应交给 S02 输出结构化 `manual_review` 或明确的手工价格维护任务。

`when_to_use`:

当前 `body_current` 要求修改既有订单、既有 Group Block、既有控房 / 配额 / Allotment / Control Block 时使用。

典型修改包括：

- 更新入住 / 离店日期。
- 更新晚数。
- 更新房型 / 房量。
- 更新人数 / 客人人数。
- 与上述核心修改同一事件出现的备注 / Trace / Guest Request；该类内容还应生成 S07 linked task。
- 更新 confirmation / group / block 关联，但不包括旧 Group Code 改为新 Group Code 的 Amend Group Code 事件。
- 维护既有控房 / 配额 / Control Block 的日期、房型、房量。
- 手工维护 Rate Code / 实际结算价格。
- 新增、修改或取消既有订单的 Fix Charge / 固定费用。

`must_not_use_when`:

- 当前邮件是在全新创建预订，应走 `new_booking_skill`。
- 当前邮件虽然含 `AMEND` / `AMEND + FINAL BOOKING`，但实质是在父团下创建多个子 `group_code` 的配合房 / Allotment；应走 `new_booking_skill`。
- 当前邮件是在取消 FIT、Group Block、Allotment 或 Control Block，应走 `cancel_booking_skill`。
- 当前邮件只是提交 Rooming List / Name List。
- 当前邮件只是收到 Voucher、Credit Voucher、payment slip 或 payment confirmation。
- 当前事件明确包含旧 Group Code 改为新 Group Code 的 Amend Group Code 动作；若该动作与日期、晚数、房型、房量、人数、价格等修改属于同一不可拆分事件，主任务应走 `amend_group_code_skill`。
- 当前邮件只是添加、修改或取消 Trace / Reservation Notes / Guest Request，且没有其他日期、晚数、房型、房量、人数、价格或控房修改；应走 `trace_reservation_notes_skill`。
- 当前邮件只是为既有订单添加、修改或取消 extra bed / 加床 / `เตียงเสริม`，且没有其他日期、晚数、房型、房量、人数、价格或控房修改；应走 `trace_reservation_notes_skill`。
- 修改动作只出现在 `body_thread`。
- 当前邮件只是 thank you、FYI、acknowledgement、noted、received、confirmed receipt、确认收到、转发说明、仅同步信息或无新业务动作。

`allowed_result_types`:

- `normal_task`
- `manual_review`

`must_not_result_types`:

- `exception_task`
- `no_action`
- `informational_message`

`key_context_needed`:

- `source_message_id`
- `source_event_index`
- `group_code`
- `confirmation_number`
- `routing_context`
- 既有 FIT / Group Block / Allotment / Control Block 上下文
- pending / open task 上下文
- active workflow 上下文
- terminated record 上下文
- before / after 所需上下文摘要
- 当前附件摘要
- 可用历史证据上下文
- 房型原文、床型、人数、是否套房、是否家庭房等房型映射线索
- 渠道 / 市场类别、supplier、备注价格、是否含早餐、用餐餐厅、实际结算价格等 Rate Code 判断线索
- extra bed / 加床 / `เตียงเสริม` 等 Trace / Guest Request 线索
- LianTai 复合单价、附加费、Fix Charge 原文线索

`input_requirements_summary`:

Main Agent 应传入当前修改请求摘要、`body_current` 原文片段、附件摘要、已提取核心 key、routing context、可用历史证据上下文，以及能帮助建立 before / after 的系统上下文或历史证据。

Catalog 不定义 before / after、房型映射或 Rate Code 的具体字段结构。

`conflict_or_fallback_rule`:

如果当前邮件明确是修改既有对象，并且 routing context 支持继续处理，输出 `normal_task`。

如果 `AMEND + FINAL BOOKING` 实质为配合房 / Allotment 创建，S02 不要求建立 before / after；应重新路由到 S01。

如果找不到原订单、前置 New Booking 未完成、目标对象不明确、邮件内容冲突、关键信息缺失、状态不允许修改、房型无法确认、房型映射 reference 无法唯一命中、Rate Code 或结算价格无法确认、Rate Code reference 无法唯一命中、before / after 无法可靠建立，统一输出结构化 `manual_review`。

如果 Rate Code 无可选代码但 reference 明确允许手工结算价格维护，且业务动作来自 `body_current`、routing context 支持继续处理、房型唯一映射、核心修改字段和 before / after 可靠、价格来自 `body_current` 或当前表格行并可可靠提取，S02 可输出 `normal_task`；输出必须包含 `rate_code=null`、`settlement_price`、`manual_settlement_price_required=true`、`manual_price_reason_code`、`price_evidence`。任一条件不满足则输出结构化 `manual_review`。

如果当前事件只是为既有订单添加、修改或取消 extra bed / 加床 / `เตียงเสริม`，不应当作普通房量修改；应路由到 `trace_reservation_notes_skill`。

如果当前事件只是为既有订单添加、修改或取消 Fix Charge，且目标订单和动作明确，可由 S02 输出 `normal_task` 并标记 `update_fix_charge`；如果目标订单、动作类型或复合单价证据不清，输出结构化 `manual_review`。

如果只是 thank you、FYI、acknowledgement、noted、received、confirmed receipt、确认收到、转发说明、仅同步信息或无业务动作，不应路由到本 Skill；明确轻量消息应由 `message_notification_skill` 输出 `informational_message`。

`tool_placeholder`:

- `suggested_tool_name: create_task_card / TBD`
- 通过统一 Tool 创建普通 Update Booking 任务卡或结构化人工复核卡。
- Update Booking 只调用一个统一任务卡创建 Tool，不按 subtype 拆多个 Tool。
- 如 `extracted_fields.fix_charge_items` 非空，任务卡 payload 应保留后续 Fix Charge 维护操作信息；真实 Fix Charge Tool / API 只能在信息系统确认目标订单 ID 后执行。

### S03 Cancel Booking Skill

`catalog_code`: `S03`

`skill_id`: `cancel_booking_skill`

`skill_name`: `Cancel Booking Skill`

`task_type`: `Cancel Booking`

`status`: `active`

`supported_subtypes`:

- `cancel_fit_reservation`
- `cancel_group_block`
- `cancel_allotment_control_block`

`cancel_object_type`:

- `fit_reservation`
- `group_block`
- `allotment_control_block`

`reference_files`:

- `references/qbd_liantai_email_table_rules.md`

说明：

- Catalog 不展开 QBD / LianTai 表格解析细则。
- 当 current 邮件、附件、发件人、主题或抽取证据显示 QBD / LianTai Excel/table workflow 时，具体 Skill 应读取 shared reference，判断高亮 / 黄色行、`CXL` 是否为当前取消动作、AMD/CXL/CFM 状态是否只是历史 / 完成证据，以及取消对象类型。

`when_to_use`:

当前 `body_current` 明确要求取消 FIT Reservation、普通团队预订、Group Block、控房、配额、Allotment 或 Control Block 时使用。

典型取消信号包括：

- cancel booking
- cancel reservation
- cancel this group
- release / cancel this block
- cancel allotment
- cancel allocation
- cancel control block
- 取消控房 / 配额
- `CXL`
- 明确要求整单取消，而不是修改

`CXL` 是常见取消缩写，可作为强取消信号；但不能只因为看到 `CXL` 字样就机械路由到本 Skill。仍需确认它是 `body_current` 中的当前动作，并结合上下文判断取消对象类型。

`must_not_use_when`:

- 当前邮件是在全新创建预订，应走 `new_booking_skill`。
- 当前邮件只是修改日期、房型、房量、人数、价格或备注，应走 `update_booking_amendment_skill`。
- 当前邮件只是释放部分房量，但仍保留订单 / 控房对象，应优先考虑 `update_booking_amendment_skill`。
- 当前邮件只是提交 Rooming List / Name List。
- 当前邮件只是收到 Voucher、Credit Voucher、payment slip 或 payment confirmation。
- 取消动作、`CXL` 或取消状态只出现在 `body_thread`。
- 当前邮件只是 thank you、FYI、acknowledgement、noted、received、confirmed receipt、确认收到、转发说明、仅同步信息或无新业务动作。

`allowed_result_types`:

- `normal_task`
- `manual_review`

`must_not_result_types`:

- `exception_task`
- `no_action`
- `informational_message`

`key_context_needed`:

- `source_message_id`
- `source_event_index`
- `group_code`
- `confirmation_number`
- `routing_context`
- 既有订单 / Group Block / Allotment / Control Block 上下文
- pending / open task 上下文
- active workflow 上下文
- terminated record 上下文
- 取消对象类型线索
- 当前附件摘要
- 可用历史证据上下文

`input_requirements_summary`:

Main Agent 应传入当前取消请求摘要、`body_current` 原文片段、附件摘要、已提取核心 key、routing context、可用历史证据上下文，以及能帮助判断取消对象类型的上下文。

如果一封邮件中同时取消多个订单，Main Agent 应拆成多个 `source_event_index`。

`conflict_or_fallback_rule`:

如果当前事件明确是取消 FIT Reservation、Group Block 或 Allotment / Control Block，且 routing context 支持继续创建取消任务，输出 `normal_task`。

如果找不到原订单、目标对象不明确、无法确认取消对象类型、前置任务未完成、订单已终止但当前邮件又提出取消、取消请求可能已经处理过、重复取消请求、邮件内容冲突、关键信息缺失，统一输出结构化 `manual_review`。

如果当前邮件像取消，但也可能是修改或部分释放房量，优先结合 routing context 判断；仍无法安全判断时输出结构化 `manual_review`。

如果只是 thank you、FYI、acknowledgement、noted、received、confirmed receipt、确认收到、转发说明、仅同步信息、确认已取消但无新业务动作，不应路由到本 Skill；明确轻量消息应由 `message_notification_skill` 输出 `informational_message`。

`tool_placeholder`:

- `suggested_tool_name: create_task_card / TBD`
- 通过统一 Tool 创建普通 Cancel Booking 任务卡或结构化人工复核卡。
- Cancel Booking 只调用一个统一任务卡创建 Tool，不按对象类型拆多个 Tool。

## 7. Message Notification And Fallback

### S10 Message Notification Skill

`catalog_code`: `S10`

`skill_id`: `message_notification_skill`

`skill_name`: `Message Notification Skill`

`task_type`: `Message Notification`

`status`: `planned / active_for_message_classification`

`supported_subtypes`:

- `thank_you`
- `fyi`
- `acknowledgement`
- `noted`
- `received`
- `confirmed_receipt`
- `forwarding_note`
- `information_sync`

`when_to_use`:

当 `body_current` 明确是 thank you、FYI、acknowledgement、noted、received、confirmed receipt、转发说明、仅同步信息，且没有新的可执行业务动作时使用。

适用场景包括：

- thank you / thanks
- FYI
- acknowledgement
- noted
- received
- confirmed receipt / 确认收到
- 转发说明
- 仅同步信息
- 无新业务动作但有沟通价值，需要用户可见

`must_not_use_when`:

- 当前邮件可以明确、安全路由到 S01 / S02 / S03 或其他业务 Skill。
- 当前邮件包含新的可执行业务动作。
- 当前邮件像业务请求，但缺少足够上下文判断任务类型。
- 当前邮件存在多个候选 Skill 冲突。
- current/history 边界不清。
- 无法判断是消息通知还是业务动作。
- 路由上下文不足以排除业务动作。

`allowed_result_types`:

- `informational_message`

`must_not_result_types`:

- `normal_task`
- `manual_review`
- `exception_task`
- `no_action`

`key_context_needed`:

- `source_message_id`
- `source_event_index`
- `body_current` 原文片段
- 附件摘要
- 已识别的消息通知语义
- 可用于确认没有新业务动作的当前邮件线索

`input_requirements_summary`:

Main Agent 应传入当前事件摘要、`body_current` 原文片段、附件摘要、候选消息通知类型，以及为什么判断为无新可执行业务动作的证据。

`conflict_or_fallback_rule`:

如果 current 邮件明确是消息通知且没有新的可执行业务动作，输出 `informational_message`。

如果无法判断是消息通知还是业务动作，不应硬走 S10，应调用 `exception_detection_skill` 输出 structured `manual_review`。

S10 不处理路由冲突、业务边界不清、current/history 不清或上下文不足。

`tool_placeholder`:

- `suggested_tool_name: create_task_card / TBD`
- 通过统一 Tool 创建信息提醒卡 / 消息通知卡。
- S10 不创建普通业务任务卡。

### S99 Exception Detection / Fallback Skill

`catalog_code`: `S99`

`skill_id`: `exception_detection_skill`

`skill_name`: `Exception Detection / Fallback Skill`

`task_type`: `Fallback`

`status`: `routing_fallback`

`supported_subtypes`:

- `route_conflict`
- `current_history_boundary_unclear`
- `insufficient_routing_context`
- `business_boundary_unclear`
- `message_or_business_unclear`

`when_to_use`:

当 Main Agent 无法安全路由到明确业务 Skill、多个 Skill 冲突、current/history 边界不清、上下文不足，或无法判断是消息通知还是业务动作时使用。

适用场景包括：

- 多个 Skill 冲突且无法安全拆分。
- current/history 边界不清。
- 邮件像业务请求，但缺少足够上下文判断任务类型。
- 无法判断当前邮件是消息通知还是业务动作。
- 路由上下文不足以安全选择业务 Skill 或 S10。

`must_not_use_when`:

- 当前邮件可以明确、安全路由到 S01 / S02 / S03 或其他业务 Skill。
- 当前邮件可以明确、安全路由到 S10 Message Notification。
- 当前邮件包含多个可拆分业务事件，且可以安全拆分为多个 `source_event_index`。

`allowed_result_types`:

- `manual_review`

`key_context_needed`:

- `source_message_id`
- `source_event_index`
- `body_current` 原文片段
- 附件摘要
- 已识别的候选 Skill
- 已提取的候选 key
- routing context
- 冲突原因或无法路由原因

`input_requirements_summary`:

Main Agent 应传入当前事件摘要、候选路由结果、无法安全路由的原因、routing context、附件摘要、可用历史证据上下文，以及是否存在 S10 候选但无法确认的原因。

`conflict_or_fallback_rule`:

当无法安全路由、多个 Skill 冲突、current/history 边界不清时，输出结构化 `manual_review`。

当无法判断是否消息通知还是业务动作时，输出结构化 `manual_review`，不要硬走 S10。

S99 第一版不输出 `informational_message`。

`tool_placeholder`:

- `suggested_tool_name: create_task_card / TBD`
- 通过统一 Tool 创建结构化人工复核卡。

## 8. Additional Planned Skills

S04-S08 已有对应 Skill 文档。Catalog 只保留路由边界、上下文要求和统一输出原则；具体业务判断、字段抽取和输出细节以对应 Skill 文档为准。S09 仍是后续占位。

### S04 Voucher Received Skill

`catalog_code`: `S04`

`skill_id`: `voucher_received_skill`

`skill_name`: `Voucher Received Skill`

`task_type`: `Voucher Received`

`status`: `planned`

`supported_subtypes`:

- `lian_tai_credit_voucher`
- `bank_transfer_slip`

`when_to_use`:

当前 `body_current` 中包含真实凭证图片 / PDF，且可判断为 LianTai 固定格式 `CREDIT VOUCHER` 或银行转账 / 存款 / payment slip / payment confirmation 凭证时使用。任务卡必须展示原始凭证图片 / PDF。

`must_not_use_when`:

- 当前邮件没有可见凭证图片 / PDF。
- 只有标题、正文关键词、泰文状态、文件名、Excel 状态或历史引用提到 voucher / payment。
- 凭证只在 `body_thread` 历史中出现。
- 仅凭图片文件名、附件文件名、Excel 行 code、客人名、日期、酒店或房型组合绑定订单。
- 从银行凭证图片的备注、参考号、QR、账号、收付款人、金额、日期或任意 OCR 文本绑定 `Group Code`。
- 从 LianTai `CODE / 團號` 字段之外读取 `Group Code`。
- 将 LianTai 展示字段用于房型映射、Rate Code、房量、价格、FIT / Group 判断或自动更新。
- 确认真实到账、生成 Receipt、直接调用 Reservation Type API 或处理 Invoice Generation。

`allowed_result_types`:

- `normal_task`
- `manual_review`

`key_context_needed`:

- current 凭证图片 / PDF 引用
- current subject / body
- voucher subtype 候选
- `Group Code` / reservation no 候选及来源
- LianTai `CODE / 團號`、日期、入住 / 离店日期、房型展示字段候选
- `routing_context` 中有效 reservation / group block / booking record 或待完善 New Booking 任务卡查询结果

`input_requirements_summary`:

Main Agent 应传入 current 凭证引用、邮件文本、subtype 证据、target key 候选、目标对象校验结果，以及原始凭证可展示引用。S04 使用统一高层字段 `voucher_attachment.display_original=true` 和 `voucher_attachment.file_reference`，不在 Catalog 展开底层附件字段。

`conflict_or_fallback_rule`:

- `lian_tai_credit_voucher` 的 `Group Code` 来自图片固定 `CODE / 團號` 字段；字段手写不清则输出 S04 `manual_review`。
- `lian_tai_credit_voucher` 不流转部门：`requires_department_routing=false`，`department_routing=[]`。
- `bank_transfer_slip` 的 `Group Code` 来自 current 邮件文本或明确相关上下文；需要通过通用 `department_routing` 流转 Finance，目的为 `confirm_payment_received`。
- 同一张银行凭证明确覆盖多个 `Group Code` 时，不算异常；按 `Group Code` 拆分多个 `ai_task_result`，每个结果只绑定一个 `case_keys.group_code`，并可用 `related_group_codes` 给页面说明同一凭证覆盖范围。
- 识别 target 后只校验是否存在有效 reservation / group block / booking record；若没有，校验是否存在可承接的待完善 New Booking 任务卡。两者都没有则输出 `manual_review`。
- S04 可传递 `post_confirm_action: update_reservation_type -> PD`，但不直接调用 API；payment slip 在 Finance 确认到账后由信息系统执行，LianTai 凭证在用户 / 信息系统确认后执行。

`tool_placeholder`:

- `suggested_tool_name: create_task_card / TBD`
- 通过统一 Tool 创建 Voucher Received 任务卡或人工复核卡；subtype 不拆 Tool。

### S05 Rooming List / Name List Skill

`catalog_code`: `S05`

`skill_id`: `rooming_list_name_list_skill`

`skill_name`: `Rooming List / Name List Skill`

`task_type`: `Rooming List`

`status`: `planned`

`supported_list_evidence_types`:

- `rooming_list`
- `name_list`
- `guest_list`
- `room_assignment_list`

`reference_files`:

- `references/qbd_liantai_email_table_rules.md`

`when_to_use`:

当前 `body_current` 提交 Rooming List、Name List、分房名单、客人名单，或发送可读取且可判断为名单的文件 / 文件链接时使用。Excel、PDF、图片、Google Drive 链接或文件名本身不是触发依据，必须能确认 current 文件内容或 current/history 语境确实指向名单。

`must_not_use_when`:

- 新建、修改、取消、Voucher / payment evidence 等主业务动作。
- 只有 Excel、文件链接或类似 `Group Code` 的文件名，不能确认是名单。
- LianTai / QBD booking update 表；例如 sheet 名类似 `BOOKING 01-2026`，或表头 / 内容是 `NEW BOOKING`、`AMEND`、`AMD`、`CXL`、`CFM`、房量、房型、价格、酒店状态。

`allowed_result_types`:

- `normal_task`
- `manual_review`

`key_context_needed`:

- current 名单事件摘要
- current 邮件正文、附件、文件链接或 `file_reference`
- 文件读取 / 下载 / 解析结果
- workbook / sheet / table / PDF / image 摘要
- 文件类型判断证据
- target key 候选及来源
- 附件 / 文件 / sheet 与目标对象绑定关系
- `routing_context`

`input_requirements_summary`:

Main Agent 应传入文件证据、读取状态、文件类型判断、target key 候选、sheet / 附件归属和目标对象校验结果。文件读取失败、无权限或无法确认类型时，不得输出 `normal_task`。

`conflict_or_fallback_rule`:

- 同一 current 事件同时包含名单和其他业务动作时，能拆则拆；不能拆则输出 structured `manual_review` 或交由 S99。
- 客人级名单通常是一行一个客人，包含姓名、英文姓名、性别、出生日期、护照、国籍、航班、到达 / 离开日期等字段。
- 一个 workbook 内多个 group / sheet 时，按目标对象拆分；每个结果只绑定一个 `case_keys.group_code` 或一个目标 reservation。
- `总名单` 默认作为 shared evidence，不单独生成任务，除非 current 明确要求按汇总 sheet 导入一个目标。
- S05 可保留 Import、TA Recorder、Note、Routing 等 locked downstream actions，但不直接导入 Opera、不创建 PM room、不维护 Routing Instruction、不写 TA Recorder / Note、不更新 Block Status。

`tool_placeholder`:

- `suggested_tool_name: create_task_card / TBD`
- 通过统一 Tool 创建 Rooming List 任务卡或人工复核卡。

### S06 Amend Group Code Skill

`catalog_code`: `S06`

`skill_id`: `amend_group_code_skill`

`skill_name`: `Amend Group Code Skill`

`task_type`: `Amend Group Code`

`status`: `planned`

`supported_action`:

- `amend_group_code`

`reference_files`:

- `references/qbd_liantai_email_table_rules.md`

`when_to_use`:

当前 `body_current`、current 附件表格、PDF 或图片 OCR 中明确要求把旧 Group Code 改为新 Group Code 时使用。`AMEND GROUP CODE TO : <new_group_code>` 是强信号；正文、附件表格、PDF、图片 OCR 都可以作为 current 证据。

`must_not_use_when`:

- 只是提到 Group Code，没有修改 Group Code 的业务动作。
- 只有一个 Group Code，无法判断旧 / 新。
- 当前事件只是普通 New / Update / Cancel / Voucher / Rooming List / Trace，且没有 Group Code 修改动作。
- 主语义是 cancel / CXL / release / cut allotment，只是顺带提到 moved / join group。
- Group Code 修改动作只出现在 `body_thread`。
- 固定列位置、固定单元格或固定 sheet 名本身作为业务识别规则。

`allowed_result_types`:

- `normal_task`
- `manual_review`

`key_context_needed`:

- current Group Code 修改原文片段
- current 附件表格 / PDF / OCR 摘要
- `old_group_code`
- `new_group_code`
- old / new 关系证据
- `routing_context`
- 同一不可拆分事件中附带的其他业务动作摘要

`input_requirements_summary`:

Main Agent 应传入当前 Group Code 修改请求、old / new 关系证据、routing context、row-level evidence 和同事件附带业务动作摘要。任务卡前端只展示 `old_group_code` 和 `new_group_code`。

`conflict_or_fallback_rule`:

- 多个业务动作可清楚拆分时，拆成多个 `source_event_index` 分别路由。
- 若 S06 与其他业务动作处于同一不可拆分事件，主任务为 S06；其他业务动作作为后台关联信息传给信息系统，不扩大任务卡前端字段。
- 受控例外：同一不可拆分事件中同时存在 Trace / Guest Request / extra bed 时，生成 S06 主任务和 S07 linked task，先 S06 后 S07。
- S06 只在“改团号语义模糊但没有明确 old / new”或 `AMEND GROUP CODE TO` 后的新 code 识别不清时输出 `manual_review`；routing context 等后续问题进入后台校验或信息系统硬校验。

`tool_placeholder`:

- `suggested_tool_name: create_task_card / TBD`
- 通过统一 Tool 创建 Amend Group Code 任务卡或人工复核卡。

### S07 Trace / Reservation Notes Skill

`catalog_code`: `S07`

`skill_id`: `trace_reservation_notes_skill`

`skill_name`: `Trace / Reservation Notes Skill`

`task_type`: `Trace / Reservation Notes`

`status`: `planned`

`supported_trace_subtypes`:

- `extra_bed`
- `general_request`

`reference_files`:

- `references/qbd_liantai_email_table_rules.md`

`when_to_use`:

当前 `body_current` 要求添加、修改或取消 Trace / Reservation Notes / Guest Request / Special Request，或需要为同一 current 事件中的 S01 / S02 / S06 后续生成 S07 linked task 时使用。

`must_not_use_when`:

- 当前事件没有 Trace、Reservation Notes、Guest Request 或 extra bed 类动作。
- 当前事件只是普通 New / Update / Cancel / Voucher / Rooming List / Amend Group Code，且没有 trace / guest request。
- 当前事件是 Cancel Booking / CXL，且只是被取消对象上历史存在 extra bed 或 guest request。
- 当前事件只是 thank you、FYI、acknowledgement、noted、received、confirmed receipt、转发说明、仅同步信息或无新业务动作。

`allowed_result_types`:

- `normal_task`
- `manual_review`

`key_context_needed`:

- current trace / guest request 原文片段
- `trace_subtype`
- `trace_text`
- `notify_departments`
- 目标 `group_code` / confirmation number / reservation number / group block key
- routing context
- history target-binding evidence，如有
- 若为 linked task，父任务 `task_type`、`source_event_index`、case key 和执行顺序

`input_requirements_summary`:

Main Agent 应传入当前 trace / guest request 摘要、原文证据、目标对象 key、routing context、subtype、部门同步判断和父任务信息。QBD / LianTai 表格场景应保留 row-level evidence。

`conflict_or_fallback_rule`:

- `trace_subtype=extra_bed` 固定输出 `trace_text=Set Extrabed`、`notify_departments=["FO","HSK"]`、`occupancy_update=3adult`、`requires_rate_update=true`、`rate_adjustment_formula=rate_code_price / 2 * 3`。
- `trace_subtype=general_request` 写具体要求；`Non-smoking room`、`High floor`、`Away from elevator`、`Same floor` 等排房要求只同步 FO；`Set Honeymoon` 等房间布置 / 房务准备同步 FO + HSK。
- S07 不决定 Rate Code，不猜 `rate_code_price`，不自行计算最终房价。
- S07 可以独立生成，也可以作为 S01 / S02 / S06 的 linked task；linked task 必须在主业务任务后执行。
- current 动作明确但目标 key 只在最近相关 history 中出现时，可使用 `body_thread` 作为 target binding evidence；history 不能单独触发 S07。
- 无法判断 subtype、目标、部门同步或 current/history 边界时，输出 S07 `manual_review` 或走 S99。

`tool_placeholder`:

- `suggested_tool_name: create_task_card / TBD`
- 通过统一 Tool 创建 Trace / Reservation Notes 任务卡或人工复核卡。

### S08 TA Recorder Skill

`catalog_code`: `S08`

`skill_id`: `ta_recorder_skill`

`skill_name`: `TA Recorder Skill`

`task_type`: `TA Recorder`

`status`: `planned`

`supported_action`:

- `maintain_ta_recorder`

`reference_files`:

- `references/qbd_liantai_email_table_rules.md`

`when_to_use`:

通常由 S05 Rooming List / Name List 派生，为每个目标 `group_code` 创建 TA Recorder linked task。少数情况下，如果 current 邮件明确要求维护 TA Recorder，且能识别唯一目标 `group_code` 和名单 / 分房文件引用，也可直接使用 S08。

`must_not_use_when`:

- S05 尚未确认名单文件、目标对象或附件绑定。
- S05 输出 `manual_review`，文件类型、目标对象或附件归属仍不清。
- 只是出现 `TA`、travel agent、旅行社、Source TA 或 Reservation Type TA。
- 只有 sheet 名、文件名或附件名像 group code。
- 只有 Google Drive / 网盘链接但文件不可下载、无权限或未确认是名单 / 分房文件。

`allowed_result_types`:

- `normal_task`
- `manual_review`

`key_context_needed`:

- S05 parent task context
- `source_rooming_list_task_id`
- `parent_source_event_index`
- `linked_task_group_id`
- 唯一目标 `group_code`
- Rooming List / Name List 附件、链接或 `file_reference`
- workbook / sheet / range 绑定证据
- file read / download / permission status
- routing context

`input_requirements_summary`:

Main Agent 应传入 S05 派生上下文、唯一目标 `group_code`、名单 / 分房附件或文件引用、文件与目标对象绑定证据和父任务关系。若一个 workbook 对应多个 group，必须消费 S05 已拆分后的目标对象结果。

`conflict_or_fallback_rule`:

- S08 是一个目标 `group_code` 一张卡；不是一封邮件一张卡、一个 workbook 一张卡或一个 sheet 一张卡。
- 同一个 workbook / `file_reference` 可以被多张 S08 共享。
- Sheet 只作为绑定证据，不直接决定 `group_code`；`IN9-17`、`总名单`、`WpsReserved_CellImgList` 不得单独生成 S08。
- 如果 S05 是 `manual_review`，S08 不应直接输出可执行 `normal_task`；可作为 locked downstream candidate 保留，或输出 S08 `manual_review`。

`tool_placeholder`:

- `suggested_tool_name: create_task_card / TBD`
- 通过统一 Tool 创建 TA Recorder 任务卡或人工复核卡。

### S09 Note Skill

`catalog_code`: `S09`

`skill_id`: `note_skill`

`skill_name`: `Note Skill`

`task_type`: `Note`

`status`: `planned_placeholder`

说明：

- 当前 `skill/` 目录下尚未落地 S09 对应 Skill 文档。
- S09 先保留为 Rooming List 后续派生任务占位；正式编写前不得把普通邮件硬路由到 S09。

`when_to_use`:

通常由 Rooming List / Name List 流程派生，用于维护 Payer code、Charge code、Breakfast 等 Note 字段。

`must_not_use_when`:

- 不应直接把普通邮件路由到本 Skill，除非 current 邮件明确要求维护 Note，或后续 Skill 文档另有定义。

`allowed_result_types`:

- `normal_task`
- `manual_review`

`conflict_or_fallback_rule`:

第一版暂按 Rooming List 的后续派生任务理解。若 current 邮件直接提出 Note 维护但上下文不足，输出结构化 `manual_review`。

## 9. Merged Or Excluded Items

### Cancel Allotment Skill

不再作为独立 Skill。

取消控房、配额、Allotment、Control Block 统一并入：

- `S03 cancel_booking_skill`
- subtype / object type: `cancel_allotment_control_block`

### Invoice Generation Skill

不纳入邮件触发 Skill Catalog。

原因：

- Invoice Generation 本来不是由邮件触发。
- 不处理“收到 invoice 邮件”的场景。
- 相关动作应走信息系统流程，而不是 AI 邮件 Skill。

### no_action

不作为第一版输出类型。

如果 current 邮件无可执行业务动作但需要用户可见，输出：

- `informational_message`

该结果类型由 `message_notification_skill` 负责输出。

### exception_task

第一版暂不作为业务 Skill 的输出类型。

如果无法安全自动处理，输出：

- `manual_review`

## 10. Current Test Scope

当前测试建议分两层覆盖：

- `S01 new_booking_skill`
- `S02 update_booking_amendment_skill`
- `S03 cancel_booking_skill`
- `S04 voucher_received_skill`
- `S05 rooming_list_name_list_skill`
- `S06 amend_group_code_skill`
- `S07 trace_reservation_notes_skill`
- `S08 ta_recorder_skill`
- `S10 message_notification_skill` 作为轻量消息分类
- `S99 exception_detection_skill` 作为 structured manual_review 路由兜底

其中：

- S01-S03 是当前核心业务回归测试。
- S04-S08 是已落地 Skill 文档的扩展业务测试。
- S09 仍是 planned placeholder，正式 Skill 文档未落地前不纳入自动路由测试。
- S10 / S99 是路由边界和兜底测试。

测试重点：

- New / Update / Cancel 是否能被正确路由。
- Voucher / Rooming List / Amend Group Code / Trace / TA Recorder 是否能按已落地 Skill 文档路由。
- `body_current` 与 `body_thread` 边界是否被遵守。
- `no_action` 是否已被移除。
- `exception_task` 是否暂未出现。
- thank you / FYI / acknowledgement / noted / received / confirmed receipt 是否走 S10 `informational_message`，而不是被业务 Skill 硬吃。
- 无法判断是消息通知还是业务动作时，是否走 S99 structured `manual_review`，而不是硬走 S10。
- `manual_review` 是否结构化保留已知字段、缺失字段、阻断点和冲突点；建议人工动作和证据位置按具体 Skill 文档执行，S04 / S05 等精简结构遵守各自例外。
- S02 subtype 是否只作为内部测试维度，不拆 Skill / Tool。
- S03 是否已覆盖 `cancel_allotment_control_block`，不再单独路由 Cancel Allotment。
- S04 是否只由 current 可见凭证图片 / PDF 触发，一张卡只绑定一个 `Group Code`，并按 subtype 正确处理 LianTai 不流转部门、payment slip 流转 Finance。
- S05 是否能区分名单文件和 QBD / LianTai booking update 表。
- S06 是否只处理 old / new Group Code 关系明确的改团号事件。
- S07 是否正确区分 `extra_bed` / `general_request`，并在 extra bed 中输出 `Set Extrabed`、FO+HSK、`3adult` 和 `rate_code_price / 2 * 3` 操作意图。
- S08 是否由 S05 confirmed target 派生，一个目标 `group_code` 一张 TA Recorder 卡。
