# 频道模型与时间线

[频道托管协议](../README.md) · [频道核心对象](../core-objects.md)

频道由创建者指定的中继托管，协议不定义迁移流程。频道创建成功后，创建者账户自动成为 owner。owner 是频道的管理角色，拥有描述更新和关闭权限；owner 与 moderator 可以发布、编辑和删除公开内容。频道描述使用连续 revision；描述更新、发帖、编辑和删除事件按托管中继接受顺序进入同一条公开时间线。

## 频道时间线生命周期

### 事件写入

频道创建成功后，托管中继把初始 `ChannelDescriptor` 作为 sequence 为 0 的创建事件。此后每次接受描述更新、帖子、编辑或删除时，为事件分配一个大于当前时间线头的 sequence，并将本次接受的完整 `ChannelDescriptor` 或内容对象作为事件的 `payload` 加入时间线。

每项时间线条目同时记录中继接受该条目的时间 `accepted_at`，以及对应描述版本 `descriptor_rev`。描述事件使用自身描述的版本，内容事件使用接受操作时生效的描述版本；创建事件的版本为 0。

sequence 表示同一频道内的接受顺序。重复发布、没有改变帖子状态的编辑、失败请求、举报和读取不产生事件。

写入遵循[原子提交与持久化规则](#原子提交与持久化规则)要求。已经分配的 sequence 不得重新分配给其他事件；清理事件后也不得重新编号仍被保留的时间线。

### 帖子编辑

帖子事件建立一篇帖子的消息 ID 及包含正文、附件和未知属性的初始状态。重复发布的识别与处理见 [`channel.post`](../methods/timeline.md#channelpost)。编辑事件不修改或替换原始帖子；客户端按托管中继分配的 sequence 应用通过验证的编辑事件。编辑可以更新正文、附件及未知属性；是否产生编辑事件按[帖子编辑](../methods/timeline.md#channelpostedit)中的状态比较规则判断。正文和附件结构见[频道内容写入规则](../methods/timeline.md#频道内容写入规则)。编辑权限不取决于目标帖作者。

单条编辑事件不提供完整帖子状态。客户端重建某一时点的帖子状态时，需要相应的帖子和编辑事件。

### 帖子删除

删除事件是目标帖的终态。追加删除事件与使目标 `ChannelPost` 及此前指向它的全部 `ChannelPostEdit` 停止通过 `channel.read` 返回，必须原子生效。删除权限不取决于目标帖作者。

符合本规范的客户端在取得并应用删除事件后，必须从本地频道时间线中移除目标帖子及其既有编辑。新客户端不会再从托管中继取得被删除的帖子及编辑正文。

删除只控制托管中继后续提供的时间线和兼容客户端的处理行为，不构成远程擦除保证。协议无法保证此前已经取得原帖的客户端会继续同步或执行删除，也无法撤回客户端另行保存或转发的副本。

### 频道关闭

`channel.close` 产生的 `ChannelDescriptor` 是频道最后一项写入。其后不得再接受任何新的描述更新、帖子、编辑或删除事件，关闭状态也不得恢复。

`channel.update`、`channel.close`、`channel.post`、`channel.post.edit` 和 `channel.post.delete` 因频道已经关闭而拒绝请求时，统一返回 [`state_conflict`](../../methods/conventions.md#错误码)。参数格式非法仍按 `bad_request` 处理；重复请求的识别与处理继续遵循各方法规则，拒绝不得改变频道状态或时间线。

### 事件保留与清理

频道处于 `active` 状态期间，事件保留与清理遵循以下规则。

每项频道时间线事件的最低保留截止时间，由该事件的 `accepted_at` 加接受时 `relay.info` 声明的 `channel_timeline_retention` 确定。除下述内容清理情形外，托管中继必须至少保留至该截止时间；后续配置调整不得缩短既有事件的最低保留期限。频道创建、描述更新、发帖、编辑和删除适用相同规则。

只要原帖仍可通过 `channel.read` 读取，指向它的全部编辑事件都必须继续保留并可按时间线读取规则取得，即使某项编辑事件自身的最低保留期限已经届满。该依赖不延长原帖本身的最低保留期限；原帖因删除或清理而停止返回后，其编辑也停止返回。

删除成功后，中继可以立即清理原帖及其既有编辑的内容，不必等待各自的最低保留截止时间。原帖因保留期限届满而被清理后，中继可以立即清理其编辑内容，不必等待编辑各自的最低保留截止时间。

删除事件必须至少保留至其自身与原帖的最低保留截止时间中较晚者，并可按时间线读取规则取得。删除事件清理后才恢复同步的客户端，可能无法获知已缓存的原帖被删除。

客户端读取、重复发布、订阅状态以及帖子因删除而停止返回，都不得刷新接受时间或重新计算原最低保留截止时间。帖子停止返回后，中继仍须至少保留其发布账户与消息 ID 的绑定、原帖 `sequence` 及重复发布内容比较所需的信息至原帖的最低保留截止时间，不能因内容清理或后续调低配置而提前删除。

清理不得改变频道时间线头、改写其余事件或复用 sequence。编辑所引用的发帖事件已经清理或停止返回时，引用目标按不可用处理。

验证这些编辑和删除事件所需的设备证书及相应 revision 的完整频道描述，必须随事件继续保留并按相应读取规则提供。

### 描述保留与权限验证

时间线中的初始 `ChannelDescriptor` 表达频道创建；后续 `ChannelDescriptor` 表达描述更新。频道处于 `active` 状态期间，最新描述必须作为当前频道状态保留。频道时间线依赖的历史描述必须完整保留；当前描述及这些历史描述的签署设备引用和对应证书也必须一并保留。当前描述、上述历史描述及各自的签署设备证书必须可通过 `channel.resolve` 取得。只要上述当前状态或依赖关系仍然成立，清理事件不得同时删除相应的频道描述或所需证书。

客户端验证内容事件时，按事件外层的 `descriptor_rev` 取得并验证对应的完整 [`ChannelDescriptor`](../core-objects.md#channeldescriptor)，确认内容操作的签名账户等于该描述的 `creator` 或列于 `moderators`。已验证的描述及其签署设备证书可以按 revision 缓存并复用。事件结构、设备证书引用和签名验证遵循[频道事件](../core-objects.md#channelevent)和[频道事件的设备证书](../core-objects.md#频道事件的设备证书)规则。

## 原子提交与持久化规则

创建、更新、关闭频道以及发布、编辑、删除帖子时，所需的托管状态、当前描述、帖子状态、完整事件及验证材料、描述版本、`accepted_at` 和 sequence 必须作为完整一致的结果原子生效。操作生效时，所依据的权限、当前 revision、频道及目标帖子状态等前置条件必须仍然成立；内容操作的权限验证和版本记录必须使用同一份当前描述。操作失败不得留下部分业务效果或推进时间线头。

中继返回成功或发送通知前，必须完成该操作所需的持久化；重启或故障恢复后，已生效的结果仍须完整一致。通知失败不回滚已经生效的频道状态和时间线。

## 信任与资源边界

客户端必须通过 Registry 和当前 `RelayDescriptor` 验证托管中继身份及 `channel.host.v1` 能力，并通过有效设备会话调用频道方法。时间线 sequence 是中继对接受顺序的声明，`accepted_at` 是中继对接受时间的声明，内容事件的 `descriptor_rev` 是中继对接受时生效描述版本的声明。

频道创建、写入、举报和订阅的资源限制遵循[资源与安全控制](../../methods/conventions.md#资源与安全控制)规则。无效签名、权限不足和 revision 回退不得改变已验证状态。
