# 语义契约

TideWeave 是同步、单进程、容量有界的嵌入式窗口状态机，可用于边缘数据处理和流处理回归测试。时间为调用方选择的非负相对整数刻度；不读取墙钟，不推测水位线，不包含消息队列或分布式一致性协议。

## 窗口

- 固定窗口采用半开区间 `[start,end)`。滚动窗口是步长等于窗口长度的滑动窗口。
- 滑动窗口支持 `slide <= size`，相位偏移 `0 <= offset < slide`；起点可为负，以完整覆盖靠近时间零的事件。
- 会话按 key 分组；相邻事件的时间差 **严格小于** gap 时相连。端点为最早事件时间及最晚事件时间加 gap。恰等于 gap 时是两个会话。
- 每个非空窗口输出 count、Int64 sum、min、max 和按 ID 排序的全部成员。无空窗口。
- 行身份是 `(key,start,end)` 三元组，字符串不通过拼接模拟复合主键。

## 原子修正与终结

- 一个事务可包含多个 put/remove。put 是按 ID 的插入或替换，remove 要求 ID 存在。同一事务内不得重复操作同一个 ID。
- 所有变更先在候选状态计算；通过全部检查才提交。不同 key 之间的移动同样原子。
- 水位线只能前进。`watermark >= end + allowed_lateness` 时窗口 final；`end <= watermark < end + allowed_lateness` 时 closing；其余 open。
- 不得改变、删除任何旧 final 行，也不得凭迟到数据新增已经 final 的行。成员也参与比较，因此等值替换成员同样不能绕过保护。
- 事务按提交前后状态判断终结性；允许一个事务内同时撤回并替代事件，从而避免中间态造成的错误拆分。
- 在相同水位线之前、相同最终事件集合可产生相同聚合行；不同水位线位置可能造成不同拒绝结果，这是显式输入语义。

## 重试与资源

- 每条命令有独立命令 ID。相同 ID、完全相同内容的成功命令重试返回 duplicate，不重复修改状态。不同内容复用成功 ID 返回 conflict。
- 拒绝的命令不消耗 ID、版本或历史容量；调用方可在修正内容后重试。
- 每次成功命令推进版本一次，包括无数据变化但 ID 新的命令。
- 检查点是带版本的成功命令日志，恢复时重新验证并回放；不承诺防篡改，也不持久化外部消费进度。
- 这是有界状态机：最多 5000 活跃事件、10000 条成功命令、每事务 128 项、滑动窗口扇出 64、最多 20000 聚合行。达到容量时原子拒绝。不会静默清理去重状态或旧事件。
- 事件时间、窗口参数与 lateness 上限为 1000000000；窗口长度／gap 与 lateness 之和不得超过 1000000000，保证所有合法窗口可在水位上限 2000000000 内终结。value 范围为 -1000000000..1000000000。边界运算在 Int64 中进行；sum 在 JSON 中用十进制字符串保持精度。
- 成功命令的规范 JSON 文本合计最多 2 Mi UTF-16 单元。检查点附加配置、计数与分隔符后仍在 8 Mi 输入上限内。历史不会静默裁剪，拒绝结果不进入检查点。

## 下游视图

`View` 接收版本连续的 `Outcome` 并原子校验 before image。缺失版本、错误旧值、重复行身份和不合形状的变更会拒绝，且不留下部分更新。最近一次成功 delivery 的完全相同重送可幂等应用。非提交 outcome 必须与当前版本、水位一致且无 delta；落后的消费者收到较新版本的 duplicate 时必须重新同步。

这是运输一致性检查，不是来源认证，也不能证明恶意发送者是否省略了应有的业务变化。调用方负责可信传输；恢复检查点也须来自可信来源。

## 执行复杂度

事务复制有界事件索引，按受影响 key 重算窗口，其余 key 复用行；会话按 `(at,id)` 排序扫描，删除中间事件可重新拆分连通分量。固定窗口扇出上限为 64。水位推进只更新已有行的 phase。差分使用真实三元组哈希索引，不以字符串分隔符构造主键。修正与输出所需开销也取决于被修改成员列表的长度。
