# S05 Rooming List / Name List Skill

## 1. Skill Identity

- catalog_code: `S05`
- skill_id: `rooming_list_name_list_skill`
- skill_name: `Rooming List / Name List Skill`
- task_type: `Rooming List`

Supported list evidence types:

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

## 2. Purpose

本 Skill 用于判断一条来自 `body_current` 的当前邮件事件，是否提交了 Rooming List / Name List / 客人名单 / 分房名单，并生成 Rooming List 任务卡候选。

第一版保持窄口径：

- current 邮件提交了可读取、可归属的名单文件 / 名单内容，且能绑定明确目标对象：输出 `normal_task`。
- current 邮件疑似提交名单，但文件不可读、类型不清、目标不清或无法安全拆分：输出 `manual_review`。

本 Skill 不直接导入 Opera，不直接创建或维护 PM room，不直接维护 Routing Instruction，不直接写 TA Recorder / Note，不直接更新 Block Status，不输出 `informational_message`。

如果本 Skill 输出 `ai_task_result` 且通过统一输出校验，AI 运行时 / Main Agent / Skill Orchestrator 后续可调用信息系统提供的统一受控 Tool / API 创建 Rooming List 任务卡或人工复核 / 人工处理任务卡。真实 TaskCard ID、任务状态机、幂等控制、并发保护、执行前硬校验、文件下载、名单导入、Routing、TA Recorder、Note 和 Block Status 更新均由信息系统负责。

## 3. Scope

本 Skill 第一版覆盖 current 邮件中的名单接收事件：

1. 邮件正文明确提交 `Rooming List` / `Name List` / `NAMELIST` / `NAME LIST`。
2. 邮件正文明确提交分房名单、客人名单或类似 guest list。
3. current 邮件发送文件 / 文件链接，且 current 或紧邻 history 表明酒店正在索要 rooming list，且文件内容可判断为客人级名单。
4. QBD / LianTai 当前事件明确为 `NAME LIST` / `Rooming List`，且名单文件证据可读取。

文件载体可以是普通附件、Google Drive / 网盘链接、系统已下载的 `file_reference`、inline 文件、PDF、图片或 Excel。文件载体本身不是触发依据，必须能判断内容或上下文确实是名单。

## 4. When To Use

当 `body_current` 中的当前邮件事件满足以下任一条件时，Main Agent 可以调用本 Skill：

- current 正文明说 `Rooming List`、`Name List`、`NAMELIST`、`NAME LIST`、分房名单、客人名单。
- current 邮件发送文件 / 文件链接，且紧邻 history 中酒店明确要求提供 rooming list，current 语义是在回复该要求。
- current 文件内容可解析，且内容明显是客人级名单结构。
- QBD / LianTai 当前事件、附件、文件内容或 current 说明明确是名单提交。

典型场景包括：旅行社发送名单 Excel、一个 workbook 包含多个 group / sheet、current 同时包含 amendment 文本和名单文件、外部链接指向名单但系统无法下载、名单附件需要和 group code / sheet 名绑定。

## 5. Must Not Use When

不得仅凭以下信号路由到 S05：

- 只有 Excel、PDF、图片或文件链接，但无法判断是名单。
- 只有文件名像 `Group Code`。
- 只有附件文件名写 `.xlsx`。
- 只有历史邮件中出现 rooming list，但 current 没有发送名单文件 / 链接 / 当前名单内容。
- current 邮件只是酒店回复已收到名单、thank you、FYI、noted，且没有新的可执行名单动作。

以下文件类型不得当作 Rooming List / Name List：

- LianTai / QBD booking update 表。
- sheet 名类似 `BOOKING 01-2026`、`BOOKING 02-2026` 的月度 booking 表。
- 表头是团号、人数、行程、酒店、备注、酒店回应状态、`UPDATE`。
- 内容是 `NEW BOOKING`、`AMEND`、`AMD`、`CXL`、`CFM`、房量、房型、价格、酒店状态。
- invoice、payment、voucher、allotment / control block 表。

如果 current 邮件主要是在新建、修改、取消、发送 voucher 或付款凭证，应优先走对应 Skill。若同一 current 邮件可安全拆分出名单事件和其他业务事件，应拆分 `source_event_index`；不能拆分时输出 structured `manual_review` 或交由 S99 fallback。

## 6. Allowed Result Types

第一版只允许：

- `normal_task`
- `manual_review`

第一版不输出：

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

## 7. Key Context Needed

Main Agent 应尽量提供以下上下文：

- `source_message_id`
- `source_event_index`
- `body_current` 中当前名单事件摘要
- current 邮件 subject
- current 邮件正文
- 可用引用历史正文，作为 rooming list 请求、target key 或 current/history 边界的证据 context
- current 邮件中的附件、inline 文件、外部文件链接或已下载 `file_reference`
- 文件读取 / 下载 / 解析结果
- workbook / sheet / table / PDF / image 的结构化摘要
- list 文件类型判断证据
- `group_code`、`confirmation_number`、reservation no、case code / block code 候选及来源
- 附件 / 文件 / sheet 与目标对象的绑定关系
- `routing_context`，包含已写入 reservation / group block / booking record 查询结果，以及可关联待完善 New Booking / 上游任务卡查询结果

注意：

- `body_thread` 只能作为辅助 context，不得单独触发 S05。
- current 业务动作必须来自 current 邮件发送名单文件、文件链接或当前名单内容。
- 文件名可以辅助附件归属判断，但不得单独触发 S05，也不得单独证明文件是名单。

## 8. Input Requirements Summary

本 Skill 输入应包含：

- 当前名单事件摘要
- current 邮件中的名单附件 / 文件链接 / `file_reference`
- 文件读取状态
- 文件类型判断证据
- 文件内可见的 header / sheet / table 摘要
- target key 候选及来源
- 文件 / sheet 与 target key 的绑定关系
- `routing_context`，如有

拆分规则：

- 如果一个 current 邮件包含多个可归属名单文件，应按目标对象拆分。
- 如果一个 workbook 包含多个 group / sheet，例如 `HD260510A-1`、`HD260510A-2`、`HD260510A-3`、`HD260510A-4`，应按 sheet / target 拆成多个输出。
- 同一个 workbook 可被多个输出共享，但每个输出必须指定对应 sheet、文件区域或绑定证据。
- `总名单`、summary、all guests 等汇总 sheet 默认作为 shared evidence，不单独生成任务；只有 current 明确要求按汇总 sheet 导入一个目标时才可单独生成。
- 最终每个 `ai_task_result` / 任务卡候选只能绑定一个 `case_keys.group_code` 或一个目标 reservation。
- 不得用数组型 `case_keys.group_code` 合并多个任务。

### 8.1 Bundled / Shared References

当 sender、subject、current 正文、附件名、文件内容或提取证据显示 QBD / LianTai Excel / table workflow 时，Main Agent 应读取：

- `../references/qbd_liantai_email_table_rules.md`

使用该 reference 的目的：

- 区分 QBD / LianTai booking update 表与名单文件。
- 遵守 current/history、表格证据、附件证据和拆行规则。
- 如果文件证据不可读、不可下载、表格类型不清或 row / sheet 归属不清，输出 structured `manual_review`，并把缺失证据写入 `manual_review.evidence_to_check`。

本 Skill 不读取房型映射或 Rate Code reference 来猜 Breakfast。Breakfast 是否显示或必填由信息系统、既有订单上下文或用户确认决定。

## 9. Decision Rules

### 9.1 Carrier Is Not Trigger Rule

Excel、PDF、图片、文件链接、Google Drive 链接或文件名本身都不是 S05 触发条件。

必须能确认以下至少一类证据：

- current 文本明确说明发送 Rooming List / Name List / 客人名单 / 分房名单。
- current 发送文件 / 链接，且紧邻 history 明确索要 rooming list。
- 文件内容可读取，并呈现客人级名单结构。

如果不能确认，不能输出 S05 `normal_task`。

### 9.2 Positive List File Evidence Rule

名单文件通常具备以下结构：

- 一行一个客人。
- 有 `姓名` / `中文姓名` / `英文姓名` / `英文姓` / `英文名`。
- 有 `护照号码` / `护照有效期`。
- 有 `性别`、`出生日期`、`国籍`、手机号等客人字段。
- 有到达 / 离开日期、航班号、参考航班信息、住宿地址等旅行字段。
- sheet 名、文件名或 current 正文能和 group code / case code 绑定。

文件是 Excel、PDF、图片或其他可解析载体都可以；关键是内容必须像客人名单或分房名单。

### 9.3 Negative Booking Table Rule

如果文件是 LianTai / QBD booking update 表，不得走 S05。

典型负向证据：

- sheet 名是 `BOOKING 01-2026`、`BOOKING 02-2026` 等。
- 表头包含团号、人数、行程、酒店、备注、酒店回应状态、`UPDATE`。
- 内容包含 `NEW BOOKING`、`AMEND`、`AMD`、`CXL`、`CFM`、房量、房型、价格或酒店状态。
- 没有客人级名单字段。

这种文件应交给 S01 / S02 / S03 或对应 Skill 判断，不得因为它是 Excel 而输出 Rooming List。

### 9.4 External Link / Unreadable File Rule

如果 current 只提供 Google Drive、网盘或外部文件链接：

- 系统能下载并解析文件，且内容是名单，才可继续输出 S05 `normal_task`。
- 链接无法打开、无权限、下载失败、解析失败或只能看到 HTML 预览页时，不得输出 `normal_task`。
- 如果 current/history 有明确 rooming list 语境，输出 S05 `manual_review`。
- 如果没有 rooming list 语境，也无法安全路由，应交由 S99 fallback 或对应 Skill。

`manual_review` 应保留链接、文件名、下载 / 解析失败状态和相关邮件上下文。

### 9.5 Current / History Boundary Rule

S05 的业务动作必须来自 current 邮件。

允许 history 作为辅助证据：

- history 中酒店要求 `Kindly provide the rooming list`。
- current 紧接着发送文件或文件链接。
- history 中的 `Group Code`、stay period、room requirement 可辅助判断文件归属。

不得只因为 history 中曾出现 rooming list 请求，就为 current 创建 S05 任务。

### 9.6 Target Object Validation Rule

S05 需要把名单绑定到具体业务对象。

可绑定 key：

- `group_code`
- `confirmation_number`
- reservation no
- case code / block code

允许 key 来源：

- current 正文
- current subject
- current 文件内容
- sheet 名
- 附件文件名，作为辅助证据
- history 中的酒店确认或索要 rooming list 上下文，作为辅助证据

目标校验只做两件事：

1. 是否存在对应有效 reservation / group block / booking record。
2. 如果不存在，是否存在可关联的待完善 New Booking 或相关上游任务卡。

如果二者都找不到，输出 `manual_review`。

S05 第一版不因为以下情况阻断：

- 是否已经有过 Rooming List。
- 是否可能重复提交。
- 是否已有 active workflow。
- 对象状态是否允许继续创建 Rooming List。

这些判断由信息系统在用户确认和后续执行时做硬校验。

### 9.7 Multi-Group / Multi-Sheet Rule

一个 current 邮件或一个 workbook 中包含多个 group / sheet 时，按目标对象拆分。

示例：

- current 写 `HD260510A -1`，sheet 写 `HD260510A-1`，二者在去空格和标准化连字符后可安全匹配，则可绑定为同一目标。
- `HD260510A-1`、`HD260510A-2`、`HD260510A-3`、`HD260510A-4` 应拆成多个 Rooming List 任务候选。
- `总名单` 默认作为 shared evidence。

如果 sheet 与 group 的对应关系不清，相关部分输出 `manual_review`。

### 9.8 S02 Update Booking Relationship Rule

如果 current 邮件同时包含 amendment / update 文本和名单文件，应拆分事件：

- amendment / update 内容走 `update_booking_amendment_skill`。
- Rooming List / Name List 文件走本 Skill。
- 如果能拆，分别生成独立 `source_event_index` 和独立 `ai_task_result`。
- 如果无法判断文件是 update 表还是名单，或无法拆分 current 动作，输出 structured `manual_review` 或 S99 fallback。

示例：

- `----AMEND------` 段落中的日期 / 房量变化走 S02。
- 同一封 current 邮件中的 `Copy of HD260510A.xlsx` 文件链接，如果可读取且文件内容是名单，走 S05。
- 如果只有 Google Drive 链接但系统打不开，走 S05 `manual_review`，不得输出 `normal_task`。

### 9.9 Downstream Action Intent Rule

S05 任务卡中应结构化保留后续动作意图，但不执行：

- `import_rooming_list`
- `pm_room_confirmation`
- `routing_instruction`
- `routing_target = Master Group`
- `ta_recorder_task_candidate`
- `note_task_candidate`
- `block_status_update_intent`

如果目标是 Group Block，用户确认后信息系统可将 Block Status 从 `TEN` 更新为 `DEF`。FIT 不适用 Group 专属 Block Status / breakfast remark。

## 10. Normal Task Output

仅当可以安全创建 Rooming List 任务时，输出：

```json
{
  "result_type": "normal_task",
  "task_type": "Rooming List",
  "current_or_history": "current"
}
```

必须同时满足：

- current 邮件确实提交名单文件、名单内容或可读文件链接。
- 文件内容或 current 语义能确认是 Rooming List / Name List。
- 能识别明确 group code / reservation no / case key。
- 能找到有效 reservation / group block / booking record，或可关联待完善 New Booking / 上游任务。
- 多 group / 多 sheet 能安全拆分。
- 每个任务的目标对象与附件 / sheet 绑定清楚。

完整输出必须符合统一输出契约。关键要求：

- `source_message_id` 必须原样带回。
- `source_event_index` 必须原样带回。
- `case_keys.group_code` 或 `case_keys.confirmation_number` 必须绑定单个目标。
- `visible_reason` 应说明 current 提交名单证据、文件类型判断、target key 来源和目标对象校验结果。
- `relevant_message_excerpt` 应来自 current 邮件文本；如果依赖 history 辅助识别，应在 `context_used` 中说明。
- `attachments` / `file_references` 必须包含当前名单文件、文件链接或可展示引用。
- `context_used` 应记录文件类型判断证据、routing context 摘要和使用的 reference 文件。
- `extracted_fields.list_evidence_type` 应填入 `rooming_list` / `name_list` / `guest_list` / `room_assignment_list`。
- `extracted_fields.file_type_validation` 应记录为什么它是名单而不是 booking update 表。
- `extracted_fields.target_object_validation` 应记录匹配到的是有效对象还是待完善 New Booking / 上游任务。
- `extracted_fields.downstream_action_intents` 应保留后续执行意图。

建议 `extracted_fields` 保留：

- `list_evidence_type`
- `file_read_status`
- `file_type_validation`
- `attachment_binding`
- `workbook_name`
- `sheet_name`
- `shared_evidence_sheets`
- `target_key`
- `target_key_source`
- `target_object_validation`
- `downstream_action_intents`
- `derived_task_candidates`

`derived_task_candidates` 可包含：

- `TA Recorder`：按 S05 已确认的目标 `group_code` 派生；一个目标 `group_code` 一张 S08 linked task，默认带入当前 Group Code，绑定 Rooming List / Name List 文件，可人工修改。同一个 workbook / file_reference 可以共享给多张 S08；sheet 只作为绑定证据，不直接决定 `group_code`。
- `Note`：包含 Payer code、Charge code、Breakfast 选择字段。

## 11. Manual Review Output

当 current 邮件疑似提交 Rooming List / Name List，但不能安全创建 `normal_task` 时，输出：

```json
{
  "result_type": "manual_review",
  "task_type": "Rooming List",
  "current_or_history": "current"
}
```

S05 的 `manual_review` 用于让用户确认文件类型、补充可读取文件、确认 target key、确认 sheet / 附件归属，或关联有效 reservation / group block / booking record / 待完善 New Booking / 上游任务卡。

本 Skill 的 `manual_review` 采用精简结构，不包含 `suggested_human_actions`。

即使输出 `manual_review`，也要尽力结构化保留：

- 已识别 group code / reservation no / case key 候选及来源。
- 文件名、链接、附件引用、`file_reference`。
- 文件读取 / 下载 / 解析失败状态。
- workbook / sheet / 文件区域候选。
- 当前邮件摘要。
- 如果能判断文件类型候选，应填入 `extracted_fields.list_evidence_type` 或 `file_type_validation.candidate_type`。
- 如果看起来是 booking update 表，应保留负向证据并说明不应走 normal S05。
- 如果 routing context 有候选对象或待完善 New Booking / 上游任务卡，应保留候选摘要。
- 不能可靠确认的字段不要猜，填 `null`、空字符串或空数组。
- 不确定原因必须写入 `manual_review.reason_code`。
- 缺失字段写入 `manual_review.missing_fields`。
- 阻塞点写入 `manual_review.blocking_points`。
- 冲突点写入 `manual_review.conflicting_points`。
- 建议人工查看的证据写入 `manual_review.evidence_to_check`。
- locked 的后续动作写入 `extracted_fields.locked_downstream_actions`，例如 Import、TA Recorder、Note、Routing 暂不执行。

建议结构：

```json
{
  "manual_review": {
    "reason_code": "",
    "visible_reason": "",
    "review_record_type": "rooming_list_manual_review",
    "blocking_points": [],
    "missing_fields": [],
    "conflicting_points": [],
    "evidence_to_check": []
  }
}
```

典型 `reason_code`：

- `file_type_unconfirmed`
- `external_file_unreadable`
- `external_file_permission_denied`
- `file_download_failed`
- `file_parse_failed`
- `missing_rooming_file`
- `rooming_context_without_readable_file`
- `booking_update_table_detected`
- `target_key_missing`
- `target_object_not_found`
- `multiple_target_objects_found`
- `sheet_group_binding_unclear`
- `multiple_group_scope_unclear`
- `current_history_boundary_unclear`
- `mixed_update_and_rooming_not_splittable`

常见 `blocking_points`：

- `excel_or_link_is_not_enough_to_classify_rooming_list`
- `external_file_cannot_be_downloaded_or_parsed`
- `file_looks_like_booking_update_table`
- `rooming_file_is_visible_but_target_key_is_missing`
- `sheet_name_and_current_group_code_do_not_match`
- `target_object_not_found_in_records_or_pending_upstream_tasks`
- `cannot_split_update_text_and_rooming_file_safely`

以下情况输出 `manual_review`：

- 只有 Excel / 链接，但不能确认是名单。
- 文件链接打不开、无权限、下载失败、解析失败。
- 文件内容不可读。
- current / history 显示应有 rooming list，但名单文件缺失。
- 文件像名单，但缺少可绑定的 group code / reservation no。
- 多个 group / sheet / 附件归属不清。
- sheet 名、正文 code、历史 group code 之间冲突。
- routing context 找不到有效对象，也找不到可关联待完善 New Booking / 上游任务。
- current 同时包含 S02 / S05 或其他动作，但无法安全拆分。
- QBD / LianTai 表格证据不可读，无法判断是 booking update 表还是名单表。

## 12. Tool Invocation Placeholder

当前创建任务卡 / 可见记录的具体 Tool / API 尚未实现，本节只预留对接位置和语义契约，不定义最终 endpoint、鉴权方式或完整返回结构。

- tool_status: `TBD`
- suggested_tool_name: `create_task_card` / `TBD`
- tool_purpose: 根据信息系统统一任务卡创建接口，创建 Rooming List 任务卡或人工复核 / 人工处理任务卡。
- tool_owner: 信息系统。
- caller: AI Runtime / Main Agent / Skill Orchestrator，最终由系统架构确认。
- invocation_timing: Skill 输出 `ai_task_result` 并通过 Unified Output Contract 校验后。
- payload_rule: Skill 能识别出的名单文件、文件类型判断、单个 target key、sheet / 附件绑定、目标对象校验结果和后续动作意图照实填入；无法安全创建时输出 `manual_review`。
- must_not_call_when:
  - Skill 输出不符合统一契约
  - current 事件完全不应进入 AI 工作台记录
  - 输出内容缺少任务卡 / 可见记录创建所需的最低溯源字段
- minimum_payload_should_include:
  - `source_message_id`
  - `source_event_index`
  - `catalog_code`
  - `skill_id`
  - `result_type`
  - `task_type`
  - `case_keys`
  - `visible_reason`
  - `relevant_message_excerpt`
  - `attachments` / `file_references`
  - `context_used`
  - `extracted_fields`
  - `manual_review`
  - `additional_operations`
  - `idempotency_key` / `TBD`
- expected_tool_result: `TBD`

Tool 设计原则：

- Rooming List Skill 只调用一个统一任务卡创建 Tool：`create_task_card`。
- TA Recorder、Note、Routing、Block Status 更新只是后续执行意图或 linked task candidates，不拆成 S05 专属 Tool。
- TA Recorder linked task 应按 S05 的目标对象拆分结果派生；不得用一个 TA Recorder 合并多个 `group_code`，也不得只凭 sheet 名生成 TA Recorder。
- AI 不直接写数据库，只调用信息系统暴露的受控 Tool / API。
- 信息系统负责文件下载、权限、解析、真实任务卡 ID、人工复核任务卡 ID、幂等、并发、状态机和最终落库。
- 信息系统在创建任务卡或执行前仍需做硬校验，不能只依赖 AI 判断。
- 如果 Tool 尚不可用，本 Skill 仍应输出合格的 `ai_task_result`；不得编造 Tool 调用结果。

## 13. Conflict Or Fallback Rule

- 如果 current 邮件同时包含 Rooming List 和 Update Booking，能拆则按 `source_event_index` 拆分，分别走 S05 和 S02。
- 如果 current 邮件同时包含 Rooming List 和 New Booking，名单事件应绑定到可关联 New Booking / 上游任务；无法确认绑定时输出 `manual_review`。
- 如果 current 邮件同时包含 Rooming List 和 Voucher / payment evidence，能拆则拆；不能拆则输出 structured `manual_review` 或交由 S99。
- 如果文件类型无法判断是名单还是 booking update 表，不得猜，输出 `manual_review`。
- 如果 current / history 边界不清，输出 structured `manual_review` 或交由 `exception_detection_skill`。
- 如果 current 邮件只是明确轻量消息通知且没有新的名单文件 / 名单动作，应由 `message_notification_skill` 输出 `informational_message`。

## 14. Must Not

- 不因 Excel 后缀直接触发。
- 不因文件名像 group code 直接触发。
- 不把 booking update 表误判成名单。
- 不直接导入名单到 Opera。
- 不直接创建 PM room。
- 不直接维护 Routing Instruction。
- 不直接写 TA Recorder。
- 不直接写 Note。
- 不直接更新 Block Status。
- 不猜 Rate Code。
- 不猜 Breakfast location。
- 不把多个 group 合并成一个任务。
- 不输出 `informational_message`。
- 不输出 `no_action`。
- 不输出 `exception_task`。
- 不把 `manual_review` 输出成空泛的“人工看一下”。
