2026-09-13 20:31:13 +08:00
|
|
|
|
# 规范:术语、契约、前提、不变量与声明边界
|
|
|
|
|
|
|
|
|
|
|
|
本文件是以下事实的唯一出处:
|
|
|
|
|
|
|
|
|
|
|
|
- 对外**术语**(本文件「术语」节);
|
|
|
|
|
|
- 本系统与外部对手方的**承诺与要求** `C-x`,以及我们向库方/上游的单方承诺;
|
|
|
|
|
|
- **待确认事项** `Qn` 注册表;
|
|
|
|
|
|
- 外部提供的**前提** `PRE-x`;
|
|
|
|
|
|
- 本系统保证的**不变量** `INV-x`;
|
|
|
|
|
|
- **声明边界** `CLM-x`:每条对外主张依赖哪些 `PRE`/`INV`、可否声明、挂起原因;
|
|
|
|
|
|
- **当前已知偏差** `G` 注册表;
|
|
|
|
|
|
- **验证映射**:验收口径的唯一清单。
|
|
|
|
|
|
|
|
|
|
|
|
编号稳定不变;条款被取代时标 `[作废 by C-y]` 并保留原文,不静默改写。不变量变更用「追加 + 作废」(`INV-7 → [作废 by INV-7b]`)。机制与领域规则见 [implementation.md](implementation.md),参数取值见 [reference.md](reference.md)。
|
|
|
|
|
|
|
2026-09-14 07:34:17 +08:00
|
|
|
|
**编号空缺**:本文件成形前已作废的旧条款未随迁移保留原文,其号码空缺且不再复用(契约段缺第 17~19 号,声明边界段缺第 1、2 号)。
|
|
|
|
|
|
|
2026-09-13 20:31:13 +08:00
|
|
|
|
## 1. 术语
|
|
|
|
|
|
|
|
|
|
|
|
| 术语 | 含义 |
|
|
|
|
|
|
|---|---|
|
|
|
|
|
|
| 上游 | 向信箱写入报文的源头系统(CIIMS、AODB 等)。 |
|
|
|
|
|
|
| 信箱 | 共享 MySQL 的入站表 `CMINMSGS`;出站方向为 `COUTMSGS`。 |
|
|
|
|
|
|
| 库方 | 共享 MySQL 的管理方;表结构变更与数据清除只能由库方执行或书面授权。 |
|
|
|
|
|
|
| 处理标记 | 信箱行上表示「本系统已处理」的约定字段;逻辑名 `DATE_PROCESSED` / `STATUS`,实际列名以库方契约为准。本系统只把空标记写成已处理值,不回撤、不覆盖。 |
|
|
|
|
|
|
| 落信 | 报文进入信箱(`CMINMSGS` 存在该行),执行方是上游。 |
|
|
|
|
|
|
| 入队 | 本系统在自有 PG 建立 `PROC_STATE` 记录,开始处理。 |
|
|
|
|
|
|
| 已回填 | 本系统已把处理标记写回该信箱行。 |
|
|
|
|
|
|
| 投递确认 | 投递目标已接受且本地 `MSG_EVENT` 已置 `SENT`;不表示业务消费者已消费。 |
|
|
|
|
|
|
| 自有 PG | 本系统唯一的业务数据库 PostgreSQL;与信箱之间不存在跨库事务。 |
|
|
|
|
|
|
|
|
|
|
|
|
管道内部术语(`W`、队头、终态、回填意图)定义在 [implementation.md](implementation.md)「术语与持久化记录」。
|
|
|
|
|
|
|
2026-09-14 07:34:17 +08:00
|
|
|
|
条款状态词只有四种:`[待确认 Qn]`(未取得对方书面确认)、`[已确认 YYYY-MM-DD]`(对方书面确认且已回写)、`[我们单方承诺]`(对外承诺,不依赖对方,已生效)、`[我们自证]`(本系统自身的架构或部署事实,无需对方确认)。
|
2026-09-13 20:31:13 +08:00
|
|
|
|
|
|
|
|
|
|
## 2. 契约
|
|
|
|
|
|
|
|
|
|
|
|
读者:库方(共享 MySQL 管理方)接口人、上游(CIIMS / AODB / SIS)接口人、本系统开发与运维。
|
|
|
|
|
|
|
|
|
|
|
|
### 2.1 共享信箱(库方)
|
|
|
|
|
|
|
|
|
|
|
|
**ID 与可见性**
|
|
|
|
|
|
|
|
|
|
|
|
- **C-1** ID 单调:信箱 ID 按提交顺序分配,已发布水位之下不再出现更小的新 ID。`[待确认 Q2]`
|
|
|
|
|
|
- **C-2** ID 分配 → 事务可见时延上界由库方**直接给出**。该值决定空洞老化阈值;**不可由 SIS 报文 `Expiry` 推导**(`Expiry` 是报文保留与传输恢复口径,与「ID 分配后多久对读事务可见」不是同一个量)。`[待确认 Q2]`
|
|
|
|
|
|
- **C-3** ID 空间不复位、不复用、不回退:含表轮换、备份恢复、`AUTO_INCREMENT` 归零。采用整表轮换方案时,新表种子必须 ≥ `max(ID)+1`,保证 ID 不断链;本系统的水位 `W` 是不可逆单游标,ID 回退会导致其后所有行永久不可见。`[待确认 Q2]`
|
|
|
|
|
|
- **C-4** 报文行不可变:同一业务身份(`SNDR|TYPE|STYP|SEQN`)的重发必为同一内容。若上游会以同一身份改发正文,需要另定识别规则(`Q15`)。`[待确认 Q15]`
|
|
|
|
|
|
|
|
|
|
|
|
**保留与清除(标记、保留期、清除前提)**
|
|
|
|
|
|
|
|
|
|
|
|
- **C-5** 处理标记值集与写权限:本系统只写入库方认可的 legacy 值集内的「已处理」值(默认值见 [reference.md](reference.md) `PARAM:mailbox.processed-value`),只写空标记、不回撤、不覆盖;内部原因(死信、重复、放弃)记录在自有 PG,**不在信箱新增枚举**。`[待确认 Q7]`
|
|
|
|
|
|
- **C-6** 清除语义必须是「标记 + 保留期」:打标本身不触发清除,触发条件是「到达保留期 `R_keep`」且「边界内全部行已打标」。若库方语义是「打标即可清除」,则清除前置条件不成立,且**增大 `R` 无法补救**,必须另行约定保留期或引入独立原文保留通道。`[待确认 Q7][待确认 Q9]`
|
|
|
|
|
|
- **C-7** 保留期下界(本文件是唯一定义处):
|
|
|
|
|
|
`R_keep ≥ max(人工重放期限 + 人工处置期限, 审计期限, 回填重试上限)`。
|
|
|
|
|
|
这是「重放窗口内原文仍在」的**唯一保证来源**。报文在 CIIMS 的 `Expiry`(480 分钟量级,`SIS:3.16`)可作为原文保留期的参照,但它是报文有效期,不等于本处所需的保留期。`[待确认 Q6][待确认 Q9]`
|
|
|
|
|
|
- **C-8** 清除前置条件(本文件是唯一定义处):执行清除时,边界内**每行必须已有终局**——即「已持有处理标记」**或**「已登记在本系统的回填放弃清单中且经人工对账确认」。放弃行不写标记,未达终态的行顺延至处理完成后清除;本系统不执行 DDL,也不写共享历史表。`[待确认 Q7][待确认 Q9]`
|
|
|
|
|
|
- **C-9** 清除执行方与方案:清除由库方执行或书面授权执行。方案 A(按 `DATE_RECEIVED` 日分区 + `TRUNCATE/DROP PARTITION`)为首选;方案 B(`CREATE TABLE ... LIKE` + 保留窗复制 + `RENAME TABLE` + 对账 + `CMINMSGS_HST` 归档 + `DROP`)为备选。现场 MySQL 版本与分区 DDL 能力待确认。`[待确认 Q9]`
|
|
|
|
|
|
- **C-10** 时间语义:时间比较与换算统一采用机场时区 `Asia/Shanghai` 及明确类型转换;`DATE_RECEIVED` 由上游/库方写入,其时钟基准需可解释(见 `PRE-4`)。`[待确认 Q7]`
|
|
|
|
|
|
|
|
|
|
|
|
**原文保留与重放**
|
|
|
|
|
|
|
|
|
|
|
|
- **C-11** 重放窗口内的原文必须可读:legacy 现役按接收超 1 天归档并删除 `CMINMSGS`;若沿用该窗口,则与 `C-7` 冲突,须以 `C-7` 为准。`[待确认 Q9]`
|
|
|
|
|
|
- **C-12** 若原文被提前清除(违反保留契约),本系统的死信处置不变,按契约违例走运维追责;该情形不改变 `C-8` 的清除前提。`[我们单方承诺]`
|
|
|
|
|
|
|
|
|
|
|
|
**我们向库方的承诺**
|
|
|
|
|
|
|
|
|
|
|
|
- **C-13** 只读约定区间的信箱行(`ID > W`),单活动实例运行,不引入并行消费者。`[我们单方承诺]`
|
|
|
|
|
|
- **C-14** 不建表、不改表结构、不迁移 schema、不写共享历史表;兼容 HTTP 入口按既有契约写入入站信箱。`[我们单方承诺]`
|
|
|
|
|
|
- **C-15** 处理标记只写 `C-5` 认可的值,不回撤、不覆盖已有非空标记。`[我们单方承诺]`
|
|
|
|
|
|
- **C-16** 回填放弃清单在对应信箱边界被清除前必须保持可查:`C-8` 以本清单作为清除授权证据之一,该证据不得随处理记录的归档或清除而消失。`[我们单方承诺][待确认 Q7][待确认 Q9]`
|
|
|
|
|
|
|
|
|
|
|
|
### 2.2 上游(SIS / AODB)
|
|
|
|
|
|
|
|
|
|
|
|
- **C-20** 业务身份四元组 `SNDR|TYPE|STYP|SEQN` 的语义由上游定义;`SEQN` 的取值范围与回绕见 `SIS:2.8.1`。**重置周期未知**,它决定业务身份是否加入日期边界(默认不加)。`SNDR` 取值域也需对拍(SIS 为 AODB/RMS,legacy 实发 OSH5 等)。`[待确认 Q11]`
|
|
|
|
|
|
- **C-21** `FLID` 在保留期内不复用。若复用,事件版本(`STATE_VERSION`)必须按 incarnation 作用域,否则「保留最新版本」的合并规则会把新航班的事件压掉,旧 tombstone 也可能删掉在用航班。`[待确认 Q16]`
|
|
|
|
|
|
- **C-22** 报文不可变(同 `C-4`)。`[待确认 Q15]`
|
|
|
|
|
|
- **C-23** 请求/应答回显契约:目标优先按已确认的回显字段精确匹配;回显未确认时的降级匹配(同类开放请求且报文 `DTTM ≥ sentAt`)存在跨代误配风险,必须明确接受并审计,不得宣称精确关联。比较前统一时区与时间单位。`[待确认 Q5]`
|
|
|
|
|
|
- **C-24** 出站信箱 `COUTMSGS`:消费方与消费顺序、`COUTMSGS_ACK_DATE_RECV` / `COUTMSGS_ACK_RESEND_TIMES` / `COUTMSGS_DATE_SENT` / `COUTMSGS_ERROR` 各列语义与写入责任、出站行清除责任与保留期、落信成功但本地未置 `SENT` 时的重复写入风险及下游去重契约,均未确认。本系统对出站的交付承诺只到**落信**为止。`[待确认 Q10]`
|
|
|
|
|
|
- **C-25** 主 / 共享删除顺序与 EROR 回报:SIS 要求删主航班前先删子共享航班,顺序不符时 RMS 应向 AODB 回发 EROR(`SIS:1.6.1-1.d`,事件定义 `SIS:4.8`);现行设计为幂等原子级联、不回发 EROR。二选一。`[待确认 Q14]`
|
|
|
|
|
|
- **C-26** 日计划缺失可选字段的语义:SIS 要求最新日计划中未发送的可选字段表示 AODB 已无该数据、子系统应删除本地值(`SIS:3.16-note-4`,RESP 同格式见 `SIS:3.17`),与现行「未携带字段保留」相反。`[待确认 Q13]`
|
|
|
|
|
|
- **C-27** 历史积压批次中「不再处理」的确认主体、审批留痕与跳过值集。`[待确认 Q12]`
|
|
|
|
|
|
|
|
|
|
|
|
**我们向上游的承诺**
|
|
|
|
|
|
|
|
|
|
|
|
- **C-28** 兼容 HTTP 入口的响应只表示**接收结果**,不表示业务处理成功:目标为现役 `ResponseDto`(`is_success` / `body`),请求体上限暂定 10MB;请求媒体类型、字符集与失败响应仍需与现役逐项对拍。`[待确认 Q3]`
|
|
|
|
|
|
- **C-29** 对外投递按**至少一次**设计,不承诺端到端恰好一次;Kafka 消息的 key 为 `FLID`,同一 `FLID` 内保序,跨 `FLID` 不承诺顺序。`[待确认 Q4]`
|
|
|
|
|
|
|
|
|
|
|
|
## 3. 前提(外部提供)
|
|
|
|
|
|
|
|
|
|
|
|
前提失效时不变量必须整体重估。
|
|
|
|
|
|
|
|
|
|
|
|
| 编号 | 前提 | 若不成立的影响 | 状态 |
|
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
|
| PRE-1 | 信箱消费权排他:同一时刻只有一个系统有权处理、打标、判定可清除(迁移期由切流规程保证单一权威写者) | 水位、身份去重、清除前提全部失效 | `[待确认]`(切流由运维规程保证,上线前另立) |
|
|
|
|
|
|
| PRE-2 | ID 单调 + 可见时延上界:见 `C-1`/`C-2` | 水位只能当快路径提示;空洞老化阈值无依据;不能声明发现完整性 | `[待确认 Q2]` |
|
|
|
|
|
|
| PRE-3 | ID 空间不复位、不复用、不回退:见 `C-3` | 水位(不可逆单游标)之后的行永久不可见 | `[待确认 Q2]` |
|
|
|
|
|
|
| PRE-4 | 报文的 `DATE_RECEIVED` 时钟基准可解释(偏斜在有界范围内) | 跨系统时间比较(`RECEIVED_AT` 与本地 `NOW`)会提前或推迟判定 | `[待确认 Q7]` |
|
|
|
|
|
|
| PRE-5 | 单活动实例运行(信箱读取不加锁、水位是单行覆盖写) | 水位互相覆盖、空洞计时失真 | `[我们自证]`(部署约束,见 architecture.md) |
|
|
|
|
|
|
| PRE-6 | 信箱与自有 PG 之间没有跨库事务 | 回填、水位推进、清除都不能声称原子 | `[我们自证]`(架构事实) |
|
|
|
|
|
|
| PRE-7 | 报文不可变:同一业务身份的重发必为同一内容:见 `C-4` | 上游改发会被判为重复并静默跳过 | `[待确认 Q15]` |
|
|
|
|
|
|
| PRE-8 | `FLID` 在保留期内不复用:见 `C-21` | 「保留最新版本」的合并规则可能压掉新航班事件,旧 tombstone 可能删掉在用航班 | `[待确认 Q16]` |
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 不变量
|
|
|
|
|
|
|
|
|
|
|
|
### 4.1 管道
|
|
|
|
|
|
|
|
|
|
|
|
- **INV-1** 五个独立事实互不替代:落信 / 入队 / 处理完成 / 已回填 / 投递确认各有独立证据,前一个不蕴含后一个。
|
|
|
|
|
|
- **INV-2** 水位与入队同事务:不允许出现「水位已推进、消息未入队」的持久化状态;水位只增不减,遇空洞即停,只有判定为永久空洞才放行,且放行只跳过空洞本身、不越过任何已存在的行。
|
|
|
|
|
|
- **INV-3** 队头唯一:任一时刻只有一个可执行队头(最小未完成 `MSG_ID`,`PENDING` 与 `FAILED` 都占位);`FAILED` 未退避到期时后续消息不得越过。
|
|
|
|
|
|
- **INV-4** 只领取已发现的行:主泵只领 `MSG_ID ≤ W`;水位之外的行只可能来自兼容入口,必须等水位追平后按序处理。
|
|
|
|
|
|
- **INV-5** 发现与处理互不阻塞:收报只看 `ID > W`,不以处理标记为谓词;终态而未回填的行不阻断后续消息的发现。
|
|
|
|
|
|
- **INV-6** 处理终态不可逆:已提交的 `SUCCEEDED` 不因回填或投递失败回改。
|
|
|
|
|
|
- **INV-7** 处理标记单调:任何路径只把空标记写成已处理值,不回撤、不覆盖。
|
|
|
|
|
|
- **INV-8** 回填只针对终态(`PENDING` / `FAILED` 永不写标记);「还欠一次回填」的事实与终态由**同一条语句**落库,不存在第二处落账。
|
|
|
|
|
|
- **INV-9** 一信一行、一身份一记录:`PROC_STATE` 按 `MSG_ID` 唯一;同一业务身份至多绑定一条有效处理记录。
|
|
|
|
|
|
- **INV-10** 对外投递至少一次;端到端恰好一次不在交付范围。
|
|
|
|
|
|
|
|
|
|
|
|
### 4.2 航班域
|
|
|
|
|
|
|
|
|
|
|
|
- **INV-11** 自有 PG 的航班当前态是唯一权威;信箱、Kafka、展示视图都不是权威。
|
|
|
|
|
|
- **INV-12** `FLID` 唯一;已写入非空的 `OPERATION_DAY` 不可改变。
|
|
|
|
|
|
- **INV-13** 每个航班每次成功状态写入单调推进 `STATE_VERSION`;重复消息不重复推进。
|
|
|
|
|
|
- **INV-14** 报文未携带的字段不被隐式清空;集合按完整合并结果写入,保留输入顺序与源序号。
|
|
|
|
|
|
- **INV-15** 缺席于某个日计划不构成删除理由;删除只由 FDEL 或受控历史清理触发。
|
|
|
|
|
|
- **INV-16** 外部副作用(回填、Kafka 投递、出站信箱)失败可重试,但不回滚已提交的本地业务结果。
|
|
|
|
|
|
- **INV-17** 状态变更、待发事件、处理终态与回填意图在同一 PG 事务内原子提交。
|
|
|
|
|
|
- **INV-18** 航班表的写者集合是「主泵处理器」与「历史清理」;两者必须互斥(同一 `PIPELINE_LOCK`,或清理在同一事务内复查判据后再删除),不得出现清理删除与处理器更新同一 `FLID` 的竞态。
|
|
|
|
|
|
- **INV-19** 整包校验失败或运营日冲突时整包不落地,既有状态与版本保持不变。
|
|
|
|
|
|
- **INV-20** 处理器幂等:同一消息重复执行只产生一次业务效果。身份唯一只防「重复记录」,不防「重新执行」;29 类 FLOP 幂等矩阵补全前,本条**不可声明**(`G-FLOP-IDEMPOTENT`)。
|
|
|
|
|
|
- **INV-21** `MAFL` 是派生投影:内容恒等于「`STATE = ACTIVE` 且 `MAID = 主航班 FLID`」的子航班集合(元素 `FLID` + `FLNO`,按 `FLID` 升序),不落库、不从入站解析;自引用与悬挂引用不入投影。
|
|
|
|
|
|
- **INV-22** 子航班集合变化必须使涉及的主航班在同一事务内推进 `STATE_VERSION` 并登记主航班事件;投影只进不退,版本不推进即被下游丢弃。
|
|
|
|
|
|
|
|
|
|
|
|
## 5. 声明边界
|
|
|
|
|
|
|
|
|
|
|
|
| 编号 | 主张 | 依赖 | 当前可否声明 | 挂起原因 |
|
|
|
|
|
|
|---|---|---|---|---|
|
|
|
|
|
|
| CLM-3 | 重放不产生重复业务副作用 | INV-20、`G-FLOP-IDEMPOTENT` | **不可** | 29 类 FLOP 幂等矩阵未补全;重放不恢复历史顺序 |
|
|
|
|
|
|
| CLM-4 | 回填不会被短暂故障放弃:最终打标,或进入可对账的放弃清单 | INV-8、`C-5`、`C-8` | **可声明(有条件)** | 条件:`R` 之前不放弃;`MISSING_ROW` 立即放弃并告警;放弃行须经人工对账才可用于清除判定(`C-8`)。原文保留另见 CLM-5 |
|
|
|
|
|
|
| CLM-5 | 重放窗口内原文仍可读 | `C-6`、`C-7`、`Q7`、`Q9` | **不可** | 清除语义与保留期未确认;「打标即清除」下无补救 |
|
|
|
|
|
|
| CLM-6 | 单实例内严格 FIFO | PRE-5、INV-3 | **可**(限于单活动实例) | — |
|
2026-09-14 07:34:17 +08:00
|
|
|
|
| CLM-7 | 事件投递在同一 `FLID` 内保序 | INV-10、投递设计 | **可**(跨 `FLID` 不承诺) | 只声明同一 `FLID` 内保序;按 `FLID` 的隔离边界与 `Q4` 定案、`G-DELIVERY-ORDER` 闭合一致 |
|
2026-09-13 20:31:13 +08:00
|
|
|
|
| CLM-8 | 出站交付承诺只到「落信」 | `C-24`、`Q10` | **可**(仅落信语义) | 消费方与 ACK 列语义未确认 |
|
|
|
|
|
|
| CLM-9 | 处理标记延迟由调度周期决定 | — | **不可** | 扫描周期不等于完成时限;批次积压、单行超时与历史作业都会延长实际延迟 |
|
|
|
|
|
|
| CLM-10 | 容量量级假设(单实例、入站日消息量千级到万级、单报文 ≤ 10⁴ 字节) | — | **不可** | 未实测,无生产负载数据;解除条件:取得现役信箱日量、峰值与单报文上限后重估 |
|
|
|
|
|
|
|
|
|
|
|
|
## 6. 验证映射
|
|
|
|
|
|
|
|
|
|
|
|
每条不变量至少一条证据。测试名以仓库现状为准;新增测试按本表补位。本表只记录**验收口径与证据位置**,覆盖进展只在 Plane(ACM2)。
|
|
|
|
|
|
|
|
|
|
|
|
| 不变量 / 声明边界 | 场景 | 证据 / 测试 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| INV-1 | 五事实互不替代:入队不引用标记、回填不引用投递、投递不引用回填 | 需接口级断言 |
|
|
|
|
|
|
| INV-2 | 重复扫描、入队中断 | 不重复入队、不丢记录;`InboxPollerTest` |
|
|
|
|
|
|
| INV-2 | 空洞老化与重置 | 阈值内不推进、不越过入队;超期只放行空洞本身;旧空洞补齐后新空洞获得完整窗口 |
|
|
|
|
|
|
| INV-2 | 水位写入与入队同事务 | 需真实 PG 事务用例 |
|
|
|
|
|
|
| INV-3 | 较小 ID 迟提交 | `InboxPollerTest` 钉住「水位越过后到达的较小 ID 不被发现」;水位遇空洞即停、空洞老化放行只跳过空洞本身 |
|
|
|
|
|
|
| INV-3 | 队头失败、退避及作业竞争 | 消息不越队;到期后恢复;作业不使消息无限饥饿 |
|
|
|
|
|
|
| INV-4 | 兼容入口与空洞并发 | `PipelineSmokeTest`「compat injected high id is not claimed until the watermark catches up」 |
|
|
|
|
|
|
| INV-5 | 终态未回填不阻断发现 | 需断言发现谓词不引用处理状态 |
|
|
|
|
|
|
| INV-6 | 投递失败后终态不变 | 需用例 |
|
|
|
|
|
|
| INV-7 | 回填四种结果 | 写入成功 / 早已标记(不覆盖、记成功)/ 信箱行不存在(立即放弃并告警,不得视为已标记)/ 暂时故障持续到 `R` 仍未打标(停止自动重试,可人工恢复) |
|
|
|
|
|
|
| INV-7 | `RECEIVED_AT` 为 NULL | 超期分支仍成立且不导致标记提前写入——判据是本地 `ENQUEUED_AT`,与库方时钟及 NULL 无关 |
|
|
|
|
|
|
| INV-8 | PG 提交失败、信箱回填失败 | 事件、终态与回填意图一起回滚;已提交结果只补写标记,不重放业务;中间态永不补写 |
|
|
|
|
|
|
| INV-8 | 非业务型终态 | 不触碰航班表 / `MSG_EVENT`,只写 `PROC_STATE`,且终态与回填意图同语句生效 |
|
|
|
|
|
|
| INV-9 | 同身份多条记录、失败后重试、归档后重复 | 只产生一次有效业务处理,不把自身重试判为重复 |
|
|
|
|
|
|
| INV-10 | 投递确认丢失、批次失败、次数耗尽 | 允许可识别的重发、保持目标顺序、整批退避并保留死信 |
|
|
|
|
|
|
| INV-11 | 权威唯一 | 需断言展示视图与缓存不得成为写入或对账来源 |
|
|
|
|
|
|
| INV-12 / INV-13 | PG 事务失败、快照重复或迟到 | 整体回滚重试、不重复推进版本、不回退状态、不误删增量航班 |
|
|
|
|
|
|
| INV-12 | 运营日冲突 | 整包 `DEAD(PROTOCOL)`,既有状态与版本不变 |
|
2026-09-14 07:34:17 +08:00
|
|
|
|
| INV-14 | 未携带字段保留、显式清空才清除;集合按完整合并结果写入 | `FlightStateEngineTest`「day plan merges scalars overwriting overlaps retaining absent and clearing on explicit empty」「flop merge retains absent scalars and collections」;`FdelAndAdftProcessorTest`「ADFT merge does not clear absent scalars」 |
|
|
|
|
|
|
| INV-14 | FLOP 逐类空标签语义(清除、撤销、集合清空)与「未携带不清空」的区分 | 逐类用例见 [implementation.md](implementation.md)「动态运行事件」;`G-FLOP-DIRECTION`、`G-FLOP-UNMAPPED` |
|
2026-09-13 20:31:13 +08:00
|
|
|
|
| INV-15 | 缺席不删除 | 需分别断言 FDEL 与清理路径 |
|
|
|
|
|
|
| INV-16 | 外部副作用失败后本地结果不变 | 需用例 |
|
|
|
|
|
|
| INV-17 | 业务型终态四件套同事务 | 需真实 PG 用例 |
|
|
|
|
|
|
| INV-18 | 清理与处理并发 | `HistorySweepJobTest`(归档后被主泵更新的航班不删除、不发 tombstone)+ `HistorySweepPurgePgTest`(删除阶段失败时 tombstone 与删除整体回滚) |
|
|
|
|
|
|
| INV-19 | 整包协议拒绝(声明数不符、运营日冲突) | `DEAD(PROTOCOL)`,整包不落地、整体回滚、既有状态不变 |
|
|
|
|
|
|
| INV-21 | `MAFL` 投影与 `ACTIVE` 子航班集合一致(子航班删除后退出、自引用与悬挂引用不入、顺序确定) | `G-MAFL`:投影未实现 |
|
|
|
|
|
|
| INV-22 | 子航班新增、删除、`MAID` 迁移时主航班版本与事件 | `G-MAFL`:主/共享级联未实现 |
|
|
|
|
|
|
| INV-20 / CLM-3 | 重放同一条消息 | 阻塞于 29 类 FLOP 幂等矩阵 |
|
|
|
|
|
|
| — | 请求超时、无匹配 RESP、时间单位不一致 | 不误用迟到应答、不提前完成请求 |
|
|
|
|
|
|
| — | stub 误配置、重复实例、停机中断 | 生产拒绝不安全启动,工作线程能正确退出 |
|
|
|
|
|
|
|
|
|
|
|
|
上表首列是**引用**(`INV-x` 的定义见本文件「不变量」);同一行可覆盖多个 `INV`,例如 `INV-20 / CLM-3`。
|
|
|
|
|
|
|
2026-09-14 07:34:17 +08:00
|
|
|
|
声明边界的证据指针:`CLM-4` 断言放弃行不写标记、不被当作已打标;`CLM-9` 由作业心跳与回填年龄指标提供观测(指标名见 [reference.md](reference.md)「指标与健康」),实际延迟仍需现场数据。
|
2026-09-13 20:31:13 +08:00
|
|
|
|
|
|
|
|
|
|
## 7. 当前已知偏差
|
|
|
|
|
|
|
|
|
|
|
|
本表是**偏差标记的唯一出处**:其他文档只在相应位置写 `G-NAME`,不解释、不记进度。偏差只写事实与受影响稳定 ID,不写负责人、日期、进度或 Plane 状态;闭合时在同一变更中删除本行与全仓 `G-NAME` 引用,关闭证据留在 Plane。
|
|
|
|
|
|
|
|
|
|
|
|
| 偏差 | 含义 | 影响 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| `G-RESP-GUARD` | `RESP` 应答守卫未实现,当前与 `DNLD` 无差别进入快照写入 | 请求匹配闭环;`C-23` |
|
|
|
|
|
|
| `G-REQ-TRACK` | `REQ_TRACK` 无运行时协调器:出站适配、请求编码、超时与应答匹配未实现 | `US-08`;`C-24` |
|
|
|
|
|
|
| `G-PROC-HST` | `PROC_STATE_HST` 未建表,终态归档未落地 | `US-11`;归档能力 |
|
|
|
|
|
|
| `G-FLOP-IDEMPOTENT` | 29 类 FLOP 幂等矩阵未补全 | `INV-20`、`CLM-3` |
|
|
|
|
|
|
| `G-REPLAY-CHANNEL` | 「打标即清除」语义下的独立原文保留通道未设计 | `CLM-5` |
|
|
|
|
|
|
| `G-MAFL` | 主航班 `MAFL` 派生投影及主/共享原子级联未实现(规则见 `INV-21`/`INV-22`);`MAFL` 不是 SIS/XML 入站字段 | 航班完整态;删除与重建 |
|
|
|
|
|
|
| `G-SRVT-VIPF` | SIS/XML 的 `SRVT`、`VIPF` 无界集合尚未映射到持久化明细;wire/domain 只保留出现事实与原始内容,不参与合并与投递(清空语义见 `Q13`) | 航班完整态;无损字段保存 |
|
|
|
|
|
|
| `G-COMPAT-HTTP` | compat 入口仍未实现 `Q3` 定案后的 ResponseDto、媒体类型、字符集、失败响应与请求体上限 | `C-28`;`US-02` |
|
|
|
|
|
|
| `G-REQ-OPEN-UNIQUE` | `REQ_TRACK` 尚无约束开放态 `(REQ_TYPE, OPERATION_DAY, SENDER)` 唯一性的部分索引 | `US-08`;`G-REQ-TRACK` |
|
|
|
|
|
|
| `G-HST-RETENTION` | 归档目标(`PROC_STATE_HST` 及后续归档表)的保留期与清除作业未定义 | 归档只转移不减少容量占用;`G-PROC-HST` |
|
|
|
|
|
|
| `G-FLIGHT-HIST-RETENTION` | 航班历史存储(外部)的保留期与容量上限未定义 | `D1`;`FLIGHT_SCHD` 物理清除后历史存储是唯一副本 |
|
|
|
|
|
|
| `G-REQ-TRACK-RETENTION` | `REQ_TRACK` 关闭态行(`DONE`/`EXPIRED`)的保留期与清除作业未定义 | 自有 PG 无界增长;`US-08` |
|
2026-09-14 07:34:17 +08:00
|
|
|
|
| `G-DELIVERY-ORDER` | 投递按目标级全序推进:一个 `FLID` 的队头失败会阻塞同目标其他 `FLID`,尚未收敛到按 `FLID` 隔离的保序边界 | 投递吞吐;`CLM-7`、`C-29` |
|
|
|
|
|
|
| `G-FLOP-DIRECTION` | 柜台、转盘、滑槽、登机门、计划机位五类的 FLOP 报文按 AODB→RMS 接收并落库,SIS 要求收到即拒绝(这些资源在 AODB 方向只随日计划下发) | `US-05`;`SIS:3.24`、`SIS:3.25`、`SIS:3.26`、`SIS:3.34`、`SIS:3.38` |
|
|
|
|
|
|
| `G-FLOP-UNMAPPED` | `XSD` `FLOP` 段的 `FFID`、`UNCL`、`CKOP`、`GTOP`、`CKCL`、`BDOP`、`LCTM`、`BDCL`、`FRET`、`FDIV`、`FLAB`、`RUNW`、`PXNO`、`FLBG`、`CKPB`、`BDPB` 未解码,解码即丢弃;其中 `FRET`、`FDIV`、`BDPB` 在 legacy 有对应处理 | `US-05`;无损字段保存 |
|
|
|
|
|
|
| `G-REF-DATA` | 参考数据入站(`SIS:3.1`~`SIS:3.14`)与 admin-api 刷新均未实现,`REF_MASTER` 只有目标表定义 | `US-13`、`US-14` |
|
2026-09-13 20:31:13 +08:00
|
|
|
|
|
|
|
|
|
|
## 8. 待确认事项台账
|
|
|
|
|
|
|
|
|
|
|
|
| 编号 | 事项 | 当前假定 | 阻塞 | 状态 |
|
|
|
|
|
|
|---|---|---|---|---|
|
|
|
|
|
|
| Q1 | 权威存储(内部方向) | 自有 PG 单库权威 + 无损明细;现场供库目标 Oracle 11g | — | 已定案(内部),Oracle 适配与部署验收另计 |
|
|
|
|
|
|
| Q2 | 信箱 ID 单调、ID 分配→事务可见时延上界、ID 空间不复位;空洞与迟到处置 | 时延按 5 分钟 `max-commit-delay`(**缺少依据的占位值**,不可由 SIS `Expiry` 推导) | 发现完整性声明、空洞老化阈值、水位不可逆性 | 未确认 |
|
|
|
|
|
|
| Q3 | HTTP 契约:媒体类型、字符集、错误码、查询接口对拍 | 目标与上限见 `C-28` | 兼容入口验收 | 未确认 |
|
|
|
|
|
|
| Q4 | Kafka wire:发送粒度、key、去重标识、分区与批次确认 | 逐 `FLID` 发送,key=`FLID` | 投递契约 | 未确认 |
|
|
|
|
|
|
| Q5 | 请求匹配:回显字段可靠性与降级匹配 | `RQFD` 60 秒 / `RQRD` 30 秒超时 | 请求跟踪闭环 | 未确认 |
|
|
|
|
|
|
| Q6 | 重放期限与人工处置期限的取值(唯一作用是决定 `R_keep` 下界) | `R` = 30 天;重放/处置期限未定 | `R_keep` 取值 | 未确认 |
|
|
|
|
|
|
| Q7 | 处理标记值集与写权限、原文保留期、处理时间语义 | 写入 `PROCESSED` | 回填值集、保留期下界 | 未确认 |
|
2026-09-14 07:34:17 +08:00
|
|
|
|
| Q8 | 逐类覆盖清单:真实报文的子类型分布、SIS 未定义的 legacy 子类型(`ABTM`/`DELY`/`PADT`/`FTSS`/`STND`/`BDPB`/`REMC`)的报文形态、admin-api 21 类清单与字段映射、逐类 golden | 航班动态的字段语义与空标签规则已由 SIS `SIS:3.19`~`SIS:3.43` 给出,参考数据类别由 `SIS:3.1`~`SIS:3.14` 给出;`VIPP` 的忽略口径 SIS 未写明 | 积压处置与逐类矩阵的差异标注 | 暂缓(现阶段不处理) |
|
2026-09-13 20:31:13 +08:00
|
|
|
|
| Q9 | 清除执行方与 DDL 授权、方案 A/B 选型、分区能力 | 首选方案 A | `R_keep` 与清除边界 | 未确认 |
|
|
|
|
|
|
| Q10 | 出站消费方、ACK 列语义、出站清理与去重契约 | — | 出站信箱 | 未确认 |
|
|
|
|
|
|
| Q11 | 上游 `SEQN` 重置周期与业务身份的日期边界 | 不含日期边界 | 身份算法 | 未确认 |
|
|
|
|
|
|
| Q12 | 积压批次「不再处理」的确认主体、审批留痕与跳过值集 | — | 积压跳过处置 | 未确认 |
|
|
|
|
|
|
| Q13 | 日计划缺失可选字段的删除语义 | 保留未携带字段;真实消息与 SIS 冲突时以真实消息为准 | 快照合并 | 暂缓(测试前不处理) |
|
|
|
|
|
|
| Q14 | 主/共享删除顺序与 EROR 回报义务 | 幂等原子级联 | 出站事件类型 | 未确认 |
|
|
|
|
|
|
| Q15 | 上游是否会以同一业务身份改发正文(决定是否需要区分「重复」与「改发」) | 假定期望不可变(`C-4`) | 身份去重语义 | 未确认 |
|
|
|
|
|
|
| Q16 | `FLID` 重用语义(决定版本是否按 incarnation 作用域) | 假定不复用(`C-21`) | 事件合并与 tombstone | 未确认 |
|
|
|
|
|
|
|
|
|
|
|
|
Q 的答复只在本表就地更新(补「结论」与日期),并触发 [README.md](README.md)「维护清单」的落地 4 步;不另开文件。
|
|
|
|
|
|
|
|
|
|
|
|
## 9. 契约数值
|
|
|
|
|
|
|
|
|
|
|
|
| 量 | 定义处 | 约束 |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| `R_keep` | `C-7` | `R_keep ≥ max(人工重放期限 + 人工处置期限, 审计期限, 回填重试上限)`;「重放窗口内原文仍在」的唯一保证来源 |
|
|
|
|
|
|
| `R` | [reference.md](reference.md) `PARAM:msgx.pipeline.overdue-backfill` | `R ≤ R_keep`;只决定强补写与放弃期限,**不保护重放窗口** |
|
|
|
|
|
|
| 去重记忆期 | `INV-9` | ≥ `R_keep`;否则「归档后重复」不成立 |
|
|
|
|
|
|
| 回填放弃清单可见期 | `C-16` | ≥ `R_keep`;否则库方清除缺 `C-8` 依据 |
|