Files
th-hotel-simple/docs/project/requirements/booking-layer-parameter-handoff-business-confirmation-draft-v1.md
T
鲨鱼辣椒 694c4317a3 checkpoint: complete recoverable V2 pre-separation baseline
Complete the selective V2 checkpoint with its minimal AgentBus, object-storage, replay persistence, and validated-workbench shared dependency closure.
2026-08-20 17:09:00 +08:00

520 lines
34 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Booking 全链路参数衔接业务确认稿 v1
| 项目 | 内容 |
| --- | --- |
| 文档状态 | 历史只读审计稿;Layer 4/5 参数口径以 ADR-002、ADR-012 和 `booking-email-contracts-v2.md` 为准 |
| 核对日期 | 2026-08-13 |
| 核对范围 | AgentBus / 手工 EML → 来源保存 → 材料 → QBD/LianTai Parser → Parsing Agent → Layer 3 → Layer 4 → Layer 5 → Layer 6 → Layer 7 → V4 任务卡 |
| 当前运行口径 | V2 默认 `SHADOW`;旧 V4 仍是临时业务写入链 |
| 业务终点 | 用户逐项确认;不写 PMS / Opera / OHIP,不核销付款,不自动通知部门 |
## 0. 这份稿请怎么确认
> 本稿不再用于继续提问或决定 Layer 5 规则。其参数盘点可作为历史证据;任何与 ADR-012 或
> `booking-business-agent-rules-v1.md` 或当前 ADR 冲突的职责、Payment、数据库历史/生命周期、
> Allotment 内容均已失效。邮件线程 History 正文已重新确认为 Layer 5 输入。
请先确认三类内容:
1. **规则确认**:每个参数从哪里来、允许怎样处理、缺失或冲突时怎么办。
2. **产品选择**:文末“待业务拍板”中的选项。
3. **实施优先级**:文末“已识别断点”是否同意作为切换新主链前的必修项。
文中状态含义:
| 状态 | 业务含义 |
| --- | --- |
| 已运行 | 正常链路正在使用 |
| 已实现但默认关闭 | 代码与测试存在,部署默认不启用 |
| SHADOW | 会计算和留证,但不是当前业务任务写入权威 |
| 仅设计 / 待接线 | 目标口径已写明,但参数还没有端到端传通 |
| 遗留待退役 | 旧链兼容能力,不应作为新口径确认 |
---
## 1. 一句话全链路
```text
邮件/附件
→ 保存“这封真实来源是什么”
→ 分出当前内容与历史内容
→ 提取来源明确写了什么
→ 补充中立语义、目标归属和材料处置
→ 查标准房型,并同时给出可适用的 Rate/早餐套餐方案
→ 首次做最终业务判断
→ 校验但不改写
→ 给员工逐项确认
→ 未来一对一生成 V4 任务卡
```
业务权力边界只有一句:**Layer 1–4 提交事实和上下文;Layer 5 才能决定是什么业务;Layer 6 只能校验;Layer 7 只能展示和确认。**
---
## 2. 横向参数衔接总表
| 业务参数 | 原始来源 | 提取/生成层 | 允许的处理 | 交给下一层 | 缺失/多个/冲突 | 当前衔接状态 |
| --- | --- | --- | --- | --- | --- | --- |
| 酒店 | 当前登录/系统酒店上下文 | 入口 | 只确定归属,不从邮件猜 | 全链 `hotel_id` | 无酒店则不处理 | 已运行 |
| 来源消息身份 | AgentBus消息ID或EML Message-ID | Layer 1 | 缺失时手工EML可按内容生成稳定ID;AgentBus缺失则保存失败 | 来源消息ID、会话ID、revision | 同ID内容变化不覆盖首次事实 | 已运行 |
| 当前/历史 | 外部会话ID、消息顺序 | Layer 1–2 | Current触发本次;History只解释 | 完整Current+有序完整History正文 | 任一历史读取不完整则整段历史不可用并阻断自动判断 | 已运行 |
| 发件人/渠道 | 邮件sender | Layer 1 / 主数据 | 规范化后精确匹配,不模糊猜 | 方向、QBD/LianTai Profile | 未匹配/多匹配保持未知 | 规则已运行;主V2非PG环境方向可能未知 |
| 团号 / Tour Code | QBD/LianTai表格或明确正文 | Parser/Layer 3 | 去首尾空白;同义来源统一为`group_code`;绝不当姓名 | Layer4订单聚合、Layer5目标身份 | 多值冲突不猜 | 主链可传,但公共Layer3未直连 |
| 来源动作 | 操作备注/G列 | Parser/Layer 3 | 只归一为来源`NEW/UPDATE/CANCEL`,不是最终业务 | Layer5结合当前态重判 | 多动作/不明确交Agent或Risk | 可传 |
| 来源动作日期 | 操作备注/G列 | Parser | 按渠道规则提取完整来源日期 | 应进入Layer3/Layer5证据 | 缺失不使用系统当前时间猜 | **当前主V2兼容桥丢失** |
| 抵店/离店/晚数 | 工作簿日期段、GROUP IN辅助 | Parser | 按物理来源段绑定;晚数=离店−抵店 | Layer4来源住期;Layer5任务参数 | 不唯一/非法不猜;历史不覆盖 | 可传;晚数当前不进入V2任务payload |
| 来源房型 | 工作簿明细 | Parser | 保留完整BF/Q10/床型/景观/套房等来源语义 | Layer4独立查Roomtype和Rate | 未知/多个/删除/冲突保持空 | 可传 |
| 标准Roomtype | 酒店目录 | Layer 4 | 只做完整标签精确规范匹配,不模糊匹配 | 应成为Layer5最终房型 | 零/多候选不选第一项 | **Layer4已算,Layer5未消费** |
| 房数 | 来源房型后的整数 | Parser | 明确缺失时按Profile规则默认1并留规则证据 | Layer4汇总;Layer5算Booking Type | 冲突不猜 | 可传 |
| 来源价格 | 紧贴房型的价格token | Parser | `8.5→850`;其他合法正数`×1000` | Layer4查Rate | 空格隔开、多值、非法不猜 | 可传 |
| 是否含早餐 | 来源房型独立BF标记 | Parser | 有BF=true;无BF=false;Q10无关 | Layer4套餐筛选 | 与餐厅/RO冲突则阻断 | Layer4已消费 |
| Rate/早餐/餐厅套餐 | 公司+规则集+来源房型+价格+早餐 | Layer 4 | 当作不可拆分原子包;同单所有房型须收敛一致 | 应整体进入Layer5/V4 | 零/多/冲突则整包空 | **仅Rate Code传到Layer5,早餐/餐厅丢失** |
| Booking Type | 独立订单有效总房量 | Layer 5 | 1–4=FIT,5+=GROUP;不看渠道名/团号/邮件文字 | 任务payload/目标定位 | 房量不完整不猜 | 规则已实现;依赖房型汇总质量 |
| 客人姓名 | 真实姓名来源 | 应由Layer3/5承接 | 与团号独立;不得用Tour Code填姓名 | Booking payload `names[]` | 缺失保持空 | **公共Parser十类事实无姓名,正式来源槽未闭合** |
| 数据库当前订单/历史任务 | 本地订单库/任务卡 | 本期不读取 | Layer 4/5/6 都不查询、不补值、不判断生命周期 | 不进入 DecisionInput/Agent | 缺来源字段直接 unresolved/人工 | 已从新权威链移除 |
| 最终业务类型 | 来源事实+Current/邮件History+目标 | Layer 5 | 只允许New/Update/Cancel/Trace/Rooming | Candidate与任务payload | 类型不明→Risk;类型已知但字段缺失保留类型并Review | 离线实现;真实Agent运行HOLD |
| Allotment效果 | source→actual中立关系+旧/扣/余房量 | Layer 5 | actual仍各自为New;source效果单独派生动作 | Layer6算术校验、Layer7确认 | 来源不足不回滚安全actual,派生动作阻断/复核 | 结构已实现 |
| 校验结论 | Candidate+原DecisionInput | Layer 6 | 只返回通过/复核/风险/拒绝,禁止改Candidate | Layer7逐项展示 | 阻断项不可确认 | 仅部分规则实现 |
| 用户确认 | Layer7逐项确认项 | Layer 7 | 只确认VALID项;记录确认人/UTC;幂等 | 确认审计;未来V4投影 | 当前不允许字段修正 | V2确认已实现 |
| V4任务卡 | validated V2 target | 确认后内部投影 | 必须1:1复制并保留run/hash来源链 | 订单任务/多卡工作台 | 无合法provenance必须拒绝 | **Gate已实现,内部投影器不存在** |
---
## 3. Layer 1:来源接入与身份
### 3.1 两个入口
| 入口 | 接收内容 | 统一后的结果 |
| --- | --- | --- |
| AgentBus实时消息 | 外部消息/会话ID、时间、sender、主题、正文、inline/附件引用 | 先保存SourceMessage,再进入统一Booking编排 |
| 手工上传EML | 邮件头、主题、正文、内嵌媒体/附件bytes | 先保存SourceMessage,再进入同一编排 |
### 3.2 身份与重复处理
- 业务幂等身份为:`酒店 + provider + channel + 外部消息ID`。
- 外部会话ID只用于串联Current与History;AgentBus frame/session ID只用于技术排查,不能代替消息身份。
- 第一次有效到达保存为`RECEIVED`。
- 同一身份重复到达且内容相同:复用原记录,不重复生成任务。
- 同一身份但内容hash变化:不覆盖第一次来源事实,标记“重复内容变化”并留差异审计;本次不继续业务处理。
- 手工EML缺Message-ID时可用内容hash生成稳定身份;AgentBus关键身份/媒体引用不合格时保存失败,不静默丢失。
### 3.3 时间、主题、正文和附件
- `received_at`优先使用来源接收时间;非法/缺失才使用系统捕获UTC时间。
- `source_sent_at`非法或缺失就保持空,不猜时间。
- 普通列表显示安全主题/摘要;确定性重放与Agent输入读取受保护的原始主题和正文。
- SourceMessage长期保存附件身份、URL引用、hash和安全摘要,不保存二进制。
- 手工EML附件bytes只在本次解析内存使用。
- AgentBus只有在专用材料预处理器可用时,才短暂下载当前Excel;否则只有安全引用,固定渠道Parser会明确提示附件bytes不可用。
**请确认 L1:** 上述“首次事实不可覆盖、内容变化不自动重跑、原文受控读取、附件二进制不长期保存”的口径是否同意?
---
## 4. Layer 2:Current / History与材料包
### 4.1 Current与History
- Current主题/正文/当前附件是本次业务触发材料。
- History按同一酒店、provider、channel、外部会话ID查找当前消息之前的全部有效消息。
- History只带完整正文、稳定消息ID、顺序和hash;不读取历史附件、URL或旧业务结论。
- History只能帮助解释当前语义或身份,不能单独触发旧New/Update/Cancel。
- 任一历史消息身份、状态、正文读取不完整:丢弃整段部分历史并给出稳定阻断码,不把残缺历史当完整历史使用。
### 4.2 附件材料
- 下游只拿逻辑附件ID、受控文件名、媒体类型、大小、内容hash、中立结构观察和证据引用。
- 不把bytes/Base64、下载URL、Cookie、Secret或数据库凭据传给Booking Agent。
- “有Excel”“有图片”“正文像付款”在本层都只是材料事实,不能直接生成Rooming List或Payment任务。
**请确认 L2:** History缺一封就整段按不可用处理,是否符合业务风险偏好?
---
## 5. Layer 3A:QBD / LianTai固定渠道Parser
### 5.1 公共规则
- 只支持精确sender:
- `op.qbdtravel@gmail.com → QBD`
- `op.liantaitravel@gmail.com → LIANTAI`
- 相似邮箱、显示名、正文联系人、文件名均不能决定渠道。
- 只处理Current `.xlsx`;不比较History附件或上一版月表。
- 多个匹配工作簿、多个业务Sheet、损坏、加密、超限、无bytes时不猜。
- 公共输出只有`facts[] + agent_materials[]`:唯一确定才出fact;原文存在但不能唯一确定则出material;完全没有则两者都不造。
- `SUCCESS`只表示Parser安全完成,不表示业务字段齐全;`FAILED`不能发布部分facts/materials。
### 5.2 Parser允许的十类来源事实
| 来源事实 | 业务含义 | 处理规则 |
| --- | --- | --- |
| 团号 | 同一订单标识 | 去首尾空白,不拆姓名 |
| 来源动作日期 | 来源记录的动作时间 | 不用系统当前时间补 |
| 来源动作类型 | NEW/AMD/CANCEL等来源标签 | 只归一来源语义,不决定最终业务 |
| 抵店日期 | 每个物理住期段的开始 | 与对应房型行状态同步,不从History补当前值 |
| 离店日期 | 每个物理住期段的结束 | 与抵店成对绑定,不从“今天”猜年份/月 |
| 晚数 | 住期长度 | 只按离店−抵店计算,不采信独立覆盖列 |
| 完整来源房型 | 原始TYPE OF ROOM | 保留BF/Q10/床型/景观/套房等 |
| 是否含早餐 | 来源BF标记 | 有BF true,无BF false,Q10无关 |
| 房数 | 房型后的数量 | 缺失按Profile确定性默认1并留规则证据 |
| 来源价格 | 紧贴房型的价格token | 8.5→850;其他合法正数×1000;不做Rate判断 |
Parser禁止产生:FIT/GROUP、最终New/Update/Cancel、标准Roomtype、Rate Code、Allotment任务、Trace、TaskCard、执行状态。
### 5.3 QBD规则
- 唯一Sheet/标题必须同时匹配QBD、Wyndham和年月,核心表头在前10行唯一。
- 核心列:Tour Code、酒店明细、操作备注、GROUP IN;F列永远完全忽略。
- 只选择四个核心格使用指定QBD橙色的业务行;其它非白色不等于有效行。
- GROUP IN只做内部日期/取消辅助,不作为公共fact。
- 动作识别:NEW、AMD BOOKING、AMD ALLOTMENT、CANCEL/CANCEL BOOKING、AMD GROUP CODE。
- 普通日期优先用GROUP IN真实日期校验明细日期;取消用明细日段+操作日期补全年月,不使用“今天”猜。
- 每个物理明细行的完整“房型+数量”块:
- 全划线=`BEFORE`
- 同行已有BEFORE且当前全未划线=`AFTER`
- 无变更对且全未划线=`CURRENT`
- 块内状态不一致=`MIXED`
- 多条活动明细保留多个来源段,不在Parser相加、覆盖或判FIT/GROUP。
- WAITING列按表头文字识别,不固定列号;已选业务行的非空整格作为员工备注材料,数字也不能当价格。
### 5.4 LianTai规则
- 当前支持August 9列表;July 7列表只做fallback/review,不猜列位。
- A团号提取;B Tour Days忽略;C人数忽略;D酒店明细提取;E晚数覆盖忽略;F导游忽略;G动作/备注;H酒店回复彻底忽略;I REMARK整段保留。
- A/D/G必须都非空、solid非白且同一底色;缺色或颜色不一致就复核。
- 同团号不同物理行仍是独立来源事件。
- D中每个`dd-dd`以Sheet年月为锚点、按原顺序解释跨月;不拿Tour Days或History补。
- 只删除受控的固定酒店/路线模板;模板外残余原文保留。office pay/confirmed只供员工看,不直接形成Payment。
- G只认带完整日期的NEW BOOKING、CANCEL BOOKING、AMEND TO;取最新日期,同日取靠后出现者;FINAL/LINE sent只是过程备注。
- 当前清楚的值可作为CURRENT/AFTER;只有原文明确old→new或划线时才产生BEFORE。
- Current正文固定问候、Update标题、提醒、联系人、页脚忽略;其它内容进入中立服务mention、员工展示或复核。
**请确认 L3A:** QBD/LianTai每一条渠道规则是否符合业务样本?尤其请重点确认F/H列彻底忽略、缺房数默认1、QBD缺价后续默认GRPA1这三项。
---
## 6. Layer 3B:Parsing Agent与本地合并
### 6.1 Agent看到什么
- 完整Current原始主题/正文。
- 完整、有序、不截断的History正文。
- 当前Parser facts/materials、系统证据注册表。
- 受控的Current-only工作簿fallback、已验证渠道/Profile/版本。
- 不发送History附件、下载URL、二进制或Secret;超过输入上限在调用前失败关闭。
### 6.2 Agent只能补什么
1. 正文里出现的中立目标候选。
2. 十类Parser角色范围内的附加候选事实。
3. 材料与目标的绑定。
4. source→actual、old→new等中立关系。
5. 加床、蜜月布置、房间布置、水牌、会议室、其它服务等中立mention。
6. 只供员工看的展示信息。
7. 每份材料的处置结果。
8. 人工复核请求。
Agent不能决定业务类型、最终动作、Trace、部门、TaskCard、标准Roomtype/Rate或执行状态。
### 6.3 本地合并权威
- Parser facts全部原样保留,Agent只能追加。
- 同一槽位同一值可合并证据;不同值不能覆盖Parser,必须阻断复核。
- 每份Parser/fallback material必须恰好处置一次,不能用“忽略”把材料静默消失。
- 未知字段、禁用字段、版本/Profile不匹配、证据引用越界、History单独触发、材料漏处置均拒绝Agent结果。
- Provider不可用、超时、输出非法等预期失败:发布Parser-only结果+BLOCKER;不使用部分回答。
### 6.4 当前实现边界
- 公共Parser+Parsing Agent CP1–CP4已实现,但真实Provider/Profile/worker默认和生产关闭。
- 主V2编排当前没有消费最终八组Layer3;它调用兼容`parseLegacy()`再投影。
- 员工展示信息、材料处置闭环、Parsing Agent新增事实尚未完整传到新Layer4/Layer5。
- Layer3旧DTO仍有“业务完整性/自动放行”字段,但该权力已撤销,属于遗留待退役。
**请确认 L3B:** 是否同意“Parser事实不可被Agent覆盖”“任何Agent失败都不使用部分回答”“History不能单独触发动作”?
---
## 7. Layer 4:来源订单上下文、标准房型与 Rate/早餐方案
### 7.1 订单怎么聚合
- 先按来源`target_ref`收集。
- 多个来源scope若有唯一相同Tour Code,合并为一个订单上下文。
- 没有唯一Tour Code的独立FIT scope保持独立,不强行合并。
- 抵离日期必须绑定`source_unit_ref`;房型/数量/价格/早餐必须再绑定`room_item_ref`。
- 缺少显式绑定就阻断,不能靠数组位置、相似名称或先后顺序配对。
### 7.2 标准Roomtype
- 只用完整来源`TYPE OF ROOM`做exact-normalized查询。
- 允许统一大小写、折叠空白、清理连字符两侧空白;不做contains/fuzzy/相似匹配。
- Company、房量、价格不能帮助“缩小”Roomtype候选。
- 对外状态只有`RESOLVED / UNRESOLVED / NOT_APPLICABLE`;缺输入、没找到、多候选或冲突用`reason_code`区分。
- 不保存或暴露“已删除来源标签”身份;未命中有效映射即是`MAPPING_NOT_FOUND`。
- 只有唯一候选时才有标准Roomtype;否则保持空,不选第一项。
### 7.3 Rate目录规则集与Booking Type不是一回事
| 渠道 | Rate目录规则集 | 目录公司 |
| --- | --- | --- |
| QBD | 永远`GROUP_AND_FIT` | `Q.B.D` |
| 普通 LianTai 的 FIT 备选 | `FIT` | `LIANTAI ONLINE/DY` |
| 普通 LianTai 的 GROUP 备选 | `GROUP` | `LIAN TAI` |
- QBD 输出一个同时适用 FIT/GROUP 的 option;普通 LianTai 不按房量预选,始终同时输出 FIT 和 GROUP 两个 option。
- Layer 5 独立根据有效总房量判断 Booking Type,然后必须取唯一对应 option,不得自由挑 Rate。
- `LIANTAI ONLINE/DY` 只是普通 LianTai 的 FIT Rate 目录键,不代表新渠道/Profile。
### 7.4 Rate+早餐+餐厅原子套餐
- 每个来源房型独立解析:目录公司+规则集+来源房型+来源价格+明确早餐/餐厅+可选主房Rate继承。
- Rate不读取标准Roomtype,保持`TYPE OF ROOM→Roomtype`和`TYPE OF ROOM+价格→Rate`两条独立链。
- 候选按完整套餐去重:`Rate Code + 是否含早餐 + 早餐餐厅`。
- 不含早餐:餐厅必须空;含早餐:餐厅只允许`LEELA`或`BUALUANG`。
- 来源“不含早却写早餐厅”或“含早却写RO”直接冲突。
- 来源未写餐厅且目录出现早餐餐厅分叉时,当前默认`BUALUANG`。
- 缺价默认目前只允许QBD:`GRPA1 + 含早餐 + BUALUANG`;若来源早餐明确与该套餐冲突,则不套默认。LianTai缺价不默认。
- One/Two Bedroom Suite可继承同订单唯一主房基础Rate;只有套房、多个主房Rate或主房未解析时不继承。
- 同一订单所有来源房型必须解析成同一套餐;任一未解或出现多个套餐,订单级套餐为空。
### 7.5 缺失和历史边界
- Layer 4 不查询数据库当前订单或历史任务,也不使用它们回填来源字段。
- 来源住期、房型、房量或 Rate 解析依赖缺失时,固定槽位保持 null/`UNRESOLVED`,转人工处理。
- 邮件 History 是另一类输入:它由 Layer 1–3 准备完整有序正文,可帮助 Layer 5 理解“本次要做什么”,但不是订单状态。
**当前 L4 已确认:** QBD缺价默认GRPA1、早餐厅缺失时默认BUALUANG、套房继承主房Rate、普通LianTai同时输出FIT/GROUP两个option、不查数据库历史。
---
## 8. Layer 5:最终业务判断
### 8.1 输入冻结
Layer5收到一份完整DecisionInput:Current全文、完整有序的邮件History正文、当前附件安全描述、
Layer3全量事实、Layer4确定性上下文、证据和版本。统一组装器必须校验同一处理批次、
同一Profile、版本一致、History连续完整、evidence closure与稳定顺序,再计算唯一SHA-256。
### 8.2 本地规则与Booking Agent分工
| 场景 | 处理者 | 规则 |
| --- | --- | --- |
| 明确酒店外发/内部邮件 | 本地规则 | 输出Ignored,不建任务 |
| 完全没有业务材料 | 本地规则 | 输出General通知 |
| 所有其他白名单入站,包括New/Update/Cancel/Trace/Rooming List/自由文本 | Booking Agent | 每封调用一次;Agent不可用或非法则fail closed Risk |
### 8.3 业务类型与 Booking Type
- Agent 使用 Current、邮件 History 和 Layer3/4 事实识别“这次要做什么”;不查询旧订单来准入或否决类型。
- 本期不检查重复New、Update/Cancel是否已存在、生命周期或较早未处理任务。
- Booking Type按合并后的有效总房量:1–4 FIT,5+ GROUP;未知留空交Layer6。
- 最终业务类型只允许:New、Update、Cancel、Trace、Rooming List。Payment只作未归类当前原文。
- Booking Type 确定后,只能消费 Layer4 中唯一匹配的 Rate/早餐 option。
- General、Risk、Ignored只作为整封消息结果通知。
- 已知业务类型但字段缺失,目标口径是保留该业务类型并Review;只有类型/目标也无法安全确定才Risk。
### 8.4 各业务参数
| 业务类型 | 当前Candidate参数 | 目标业务含义 |
| --- | --- | --- |
| New/Update/Cancel | Booking Type、对象类型、姓名、抵离日期、房型+房数、Rate Code | 表达一笔预订生命周期动作 |
| Trace | 服务文本数组、一个部门 | 形成订单备注事项 |
| Rooming List | 附件ID、材料证据 | 提醒员工处理名单,不解析名单、不导入PMS |
| Payment | 附件ID、材料证据 | 展示凭证,不核对到账、不改付款状态 |
| Allotment派生动作 | 来源旧房量、实际扣减、余量、每个actual贡献 | actual仍各自New;source效果独立确认 |
### 8.5 当前尚未传通的参数
- Parsing Agent 最终八组 Layer3 尚未 handoff 给新 Layer4/5 权威链。
- Rooming List typed resolver 尚未完整接线。
- 用户最终确认精确`ONE-BEDROOM-SUITE-DBL→RM2`并已落库;不得扩展到其他含DBL的套房标签。
- 公共固定渠道Layer3没有正式姓名槽;`names[]`通常为空。
- Trace结构比现有V4卡片窄:不能表达每条事项自己的类型、部门、加床目标房型和数量。
**请确认 L5:** 是否同意Layer5是唯一业务判断权威,以及Agent不可用时宁可Risk也不回退旧业务判断?
---
## 9. Layer 6:规则校验
### 9.1 当前已实现
- Candidate必须属于同一DecisionInput、同一processing run,input hash一致。
- 校验前后Candidate hash必须完全不变。
- target/derived ID不能重复。
- 目标身份不唯一时要求复核。
- Booking:Booking Type必填;非取消必须有抵店、离店、至少一个房型项。
- Trace:部门必填。
- Rooming List:当前要求至少一个附件ID。
- Payment:至少一个材料证据。
- Allotment:actual引用闭合、贡献集合一致、贡献总房量=扣减量、旧量−扣减量=余量、余量不能负;整块取消余量必须为0。
### 9.2 当前未实现
- Candidate房型是否逐项等于Layer4标准Roomtype。
- Candidate Rate是否等于Layer4完整Rate/早餐/餐厅套餐。
- New是否重复、Update/Cancel是否有唯一活动订单、Cancel后再Update等生命周期。
- 当前邮件与同订单历史任务的先后顺序。
- 每条证据是否完整闭包、每个Allotment contribution独立校验状态。
- V4的Basic Information前置与同订单任务顺序。
### 9.3 状态含义
| 状态 | 业务含义 | 是否可确认 |
| --- | --- | --- |
| VALID | 当前已实现规则全部通过 | 是 |
| REVIEW_REQUIRED | 类型/参数已知但需人补充或核对 | 当前V2否 |
| RISK | 业务不能安全决定 | 否 |
| REJECTED | 契约/引用/算术等硬错误 | 否 |
当前实现里,“需要人工复核”的问题在底层严重级别也标成`BLOCKER`;产品展示时需要区分“可人工补正”和“系统硬错误”,否则员工会把两者理解成同一种故障。
**请确认 L6:** 是否同意只有VALID可直接确认?若同意,必须同时决定Review项应如何修正,否则Review会永久卡住本次run。
---
## 10. Layer 7:展示与人工确认
### 10.1 投影规则
- 每个Target、Allotment派生动作、消息通知分别成为一个展示项。
- 页面只复制Layer5参数和Layer6状态,不重算房量、不重新判断业务、不合并Allotment。
- Target/Derived为VALID才可勾选确认;Review/Risk/Rejected不可确认。
- 消息通知只展示,不能“确认成任务”。
### 10.2 确认规则
- 用户可部分确认多个VALID项;同一项重复提交幂等。
- 保存确认项、确认人和UTC时间。
- 尚有有效项未确认或存在Review项:`PARTIALLY_CONFIRMED`。
- 所有可确认项完成且没有Review:`CONFIRMED`。
- V2当前禁止任何字段override;要修正Candidate,服务端提示“形成新的来源revision重新跑”。
- 当前没有V2 review-resolution接口,也没有从页面创建“人工修正版revision”的入口,所以Review项不能在本run内闭环。
### 10.3 当前前端体验
- 页面展示run状态、来源消息ID、revision、结果类型、证据数量、处理时间线。
- V2把整个Candidate作为只读JSON展示;问题只显示code,证据不展开为业务原文定位。
- 默认勾选全部尚未确认的VALID项;用户可取消部分勾选。
- V2没有retry入口。
- 后端查询只要求“任务读取”权限,确认要求“任务编辑”权限;但前端整页路由要求“任务编辑”,只读用户无法进入。
- V2把“确认”归到“编辑任务草稿”权限,而现有V4使用独立的“确认任务”权限,员工权限含义不一致。
**请确认 L7:** 你希望确认页是“不可改、错误则新revision”,还是“Review项可在白名单内修正并保留原Candidate+修正审计”?见文末D08。
---
## 11. V2确认后到V4任务卡
### 11.1 目标口径
- 只有validated V2 Candidate能生成新V4业务任务。
- 每个V4 Event一对一引用一个TargetDecision,业务类型和字段必须逐项复制。
- V4必须保存:契约版本、run ID、target ID、candidate hash、validation hash。
- 外部SuperAgent callback不能伪装“系统内部已校验投影”。
- 任何不一致都拒绝写卡,不能“差不多就创建”。
### 11.2 当前现状
- provenance字段、数据库列和强校验Gate已经存在。
- **生产代码没有可信内部V2→V4投影器;架构测试还明确要求当前调用者为空。**
- 因此:
- `SHADOW`:V2计算/留证;旧V4仍创建业务任务。
- `CAPTURE_ONLY`:只捕获并产生Risk,不创建旧或新业务任务。
- `AUTHORITATIVE`:禁止旧链;但目前也没有内部投影器创建V4卡,所以链路停在V2确认审计。
- V2确认本身不会调用PMS/Opera,也不会自动生成付款/部门动作。
### 11.3 V2与现有V4字段差异
| 主题 | V2 Candidate | 现有V4任务卡 | 需要对齐 |
| --- | --- | --- | --- |
| Basic Information | 无Account/Market/Source | 当前有Basic卡且必须先确认 | 目标展示仅限New Booking;列为Sender/Account/Market/Source,QBD邮箱→QBD/gtt/TA,LianTai邮箱→LIANTAI/gtt/TA;其他任务类型不展示,尚待实施 |
| New Group场景 | 无STANDARD/PROPOSAL | 有booking_scenario | 是否保留 |
| Update | 类似完整Booking payload,含Rate | 稀疏`after`,Rate禁止修改 | 以哪一套为准 |
| 标准房型 | 当前仍是来源房型文本 | 要求目录Roomtype code | 必须改为Layer4结果 |
| 早餐 | Candidate只有Rate Code | V4展示会从目录派生早餐 | 是否以Layer4原子套餐为唯一权威 |
| Trace | 多条服务共用一个部门 | 每条事项有类型/部门/加床参数 | 扩展V2或降级V4 |
| Rooming List | V2要求附件非空 | V4允许纯事项卡无附件ID | 统一必填口径 |
| 复核修正 | V2禁止字段override | V4允许白名单修正并留审计 | 统一产品流程 |
| 同订单顺序 | V2 Layer6未做 | V4有Basic前置和同订单顺序 | 放在哪一层校验 |
---
## 12. 当前权威链、影子链和遗留链
| 路径 | 当前作用 | 是否写业务任务 |
| --- | --- | --- |
| V2 Layer1–7 | 目标权威架构;默认SHADOW计算、持久化、可展示/确认 | 默认否 |
| 公共Parser+Parsing Agent CP1–CP4 | 固定渠道目标Layer3能力;Provider/worker默认关闭 | 否 |
| `parseLegacy()`兼容投影→V2 | 当前主V2实际取得固定渠道来源事实的桥 | 只供V2影子结果 |
| 旧V4手工EML / AgentBus→SuperAgent链 | SHADOW模式下的临时业务写入权威 | 是 |
| contracts-v1 PostgreSQL主线 / Field Recovery | 遗留、默认关闭、逐步退役 | 仅显式开启时 |
结论:**当前不能用“新七层架构已完成”描述现状。准确说法是:架构和多段能力已实现,但关键参数衔接与确认后任务卡投影尚未闭环。**
---
## 13. 已识别的主链断点
| 编号 | 断点 | 业务影响 | 建议Gate |
| --- | --- | --- | --- |
| G01 | 公共Parser/Parsing Agent最终Layer3未接主V2 | Agent补充、员工备注、材料处置没有进入后续权威链 | AUTHORITATIVE前必须完成 |
| G02 | `SOURCE_ACTION_DATE`在兼容桥丢失 | 无法完整审计来源动作时间 | AUTHORITATIVE前必须完成 |
| G03 | 姓名没有正式Layer3来源槽 | `names[]`缺来源闭环,不能稳定展示/建卡 | 字段契约先确认 |
| G04 | Layer4标准Roomtype未传Layer5 | Candidate/V4可能拿来源房型而非酒店代码 | AUTHORITATIVE前必须完成 |
| G05 | 早餐/餐厅原子套餐未传Layer5 | Rate与早餐可被拆散,无法做等值校验 | AUTHORITATIVE前必须完成 |
| G06 | Layer4当前订单在新结构,Layer5读旧空结构 | Update/Cancel生命周期不能按目标规则判定 | AUTHORITATIVE前必须完成 |
| G07 | Layer6缺Room/Rate/lifecycle/duplicate/order校验 | 错误Candidate可能被标VALID | AUTHORITATIVE前必须完成 |
| G08 | V2 Review不可修正也不可确认 | 部分run永久卡住 | 产品流程先确认 |
| G09 | V2→V4内部投影器不存在 | AUTHORITATIVE确认后没有正式任务卡 | AUTHORITATIVE前必须完成 |
| G10 | V2/V4字段结构不一致 | 即使投影器存在也无法无损1:1复制 | 先完成字段对齐 |
| G11 | V2前端展示整包JSON,复核项与硬错误的严重级别也未清晰区分 | 非技术用户难以核对字段、证据和问题性质 | 上线前改为业务表单并分级展示 |
| G12 | 页面读取和确认权限不一致,V2/V4确认权限也不一致 | 有读取权限的员工打不开处理页;同一个“确认”动作授权含义不同 | 上线前对齐 |
---
## 14. 待业务拍板清单
请按“同意推荐 / 选择另一项 / 补充规则”回复编号即可。
| 编号 | 需要确认的问题 | 推荐口径 | 另一种选择 | 影响 |
| --- | --- | --- | --- | --- |
| D01 | QBD来源没写价格时怎么办 | 继续默认`GRPA1+含早+BUALUANG` | 一律人工确认 | 自动化率与误价风险 |
| D02 | 来源写含早但没写餐厅,目录存在LEELA/BUALUANG分叉 | 默认BUALUANG | 保持多候选、人工选餐厅 | 早餐落地准确性 |
| D03 | 套房没有自身Rate时 | 继承同订单唯一主房基础Rate,套房早餐条件仍独立校验 | 套房一律人工确认 | 套房自动Rate比例 |
| D04 | 来源固定槽完整时是否仍查历史 | 不查;历史不能影响来源事实 | 每封都查作只读提示 | 性能、复杂度、历史污染风险 |
| D05 | History任一消息读取失败 | 整段History不可用并阻断自动判断 | 使用其余可读History并标记不完整 | 语义误判风险 |
| D06 | 真实姓名放在哪层 | 在Layer3新增独立的中立姓名/身份结构并保留来源证据;不挤进已冻结的Parser十类facts,仍不得用团号填姓名 | 升级Parser契约版本并扩展正式fact角色,或只允许Layer5 Agent从全文生成姓名 | 契约变更与审计性 |
| D07 | Update的业务参数模型 | 采用稀疏`after`,只表达本次变更;当前订单单独展示,Update不得改Rate | 使用完整最终快照并允许Rate | 与V4、审计和并发合并方式 |
| D08 | V2 Review如何闭环 | 允许白名单修正;保留原Candidate,另存修正值/人/时间/证据,不让Layer7重算 | 禁止修改;必须通过明确的“创建人工修正版revision”流程重跑 | 员工处理效率与审计模型 |
| D09 | Rooming List是否必须有附件 | 不必;正文明确事项也可成卡,附件有则关联 | 必须至少一个附件 | 与现有V4口径一致性 |
| D10 | Trace结构 | 每条事项独立类型、部门、目标房型、数量;部门不明可Review | 继续整张Trace共用一个部门 | 加床/多部门准确性 |
| D11 | Basic Information从哪里来 | 系统按sender/酒店目录精确派生Account,再派生Market/Source;未唯一则独立Review | Booking Agent输出Account | 主数据权威与V4前置 |
| D12 | V2确认和V4卡片确认是否保留两次 | 合并为一次员工业务确认:确认V2项时事务性创建/确认V4初始卡或直接进入同一办理页 | 保留“V2参数确认+V4卡片确认”两次 | 员工重复操作与审计层级 |
| D13 | 确认页默认勾选 | 默认不勾选,员工主动确认每项 | 保持默认勾选全部VALID项 | 误操作风险 |
| D14 | 消息通知是否需要已读动作 | General/Risk在来源通知页允许独立ACK,但ACK不变成业务任务 | 仅展示、永不ACK | 工作台待办闭环 |
| D15 | 查看、修改、确认分别用什么权限 | 页面查看用“任务读取”;修正草稿用“任务编辑”;最终确认统一用独立“确认任务”权限 | V2继续把最终确认视作“编辑任务草稿” | 职责分离与误授权风险 |
| D16 | AUTHORITATIVE切换条件 | G01–G12关闭+脱敏E2E+回滚/监控通过后才切 | 允许带缺口灰度 | 生产风险 |
---
## 15. 建议的最终确认顺序
1. 先确认D01–D05:来源提取与Rate/History规则。
2. 再确认D06–D11:最终业务参数模型。
3. 再确认D12–D15:员工页面、确认流程与权限。
4. 最后确认D16:什么时候允许从SHADOW切到AUTHORITATIVE。
在D06–D12没有定稿前,不建议直接开发V2→V4投影器,因为投影字段和确认流程仍会返工。
---
## 16. 本稿的非范围
- 不决定PMS/Opera/OHIP接口参数。
- 不执行库存扣减、付款核销、Rooming List导入或部门派单。
- 不授权真实Booking Agent/Parsing Agent上线。
- 不把旧V1/V4的提前业务判断重新纳入新链。
- 不把本稿中的“推荐口径”视为已确认决定;需业务明确回复后再写入正式ADR/契约。