# 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/契约。