# 2026-06-01 变更记录

## [docs] 整理项目改进优先级与后续开发方向

### 变更内容
- 新增项目级 `TODO_LIST.md`，将当前代码库可改进的问题和后续开发方向按优先级整理为待办清单
- 将近期需要优先修复的稳定性、测试、文档同步和 API 一致性问题单独提升为高优先级事项
- 补充中长期方向，包括 feature 验证矩阵、集成测试基建、发布质量门槛和示例工程扩展

### 涉及文件
- `TODO_LIST.md` [Changed] 写入按 P0 至 P3 分层的项目待办与推荐执行顺序
- `changelogs/2026-06-01.md` [Added] 新增当天变更记录，登记本次文档整理

### 影响
- 为后续迭代提供统一的优先级参考，便于先处理稳定性和可信度问题，再推进能力扩展
- 不影响现有库行为，仅补充项目管理与开发规划文档

### 原因
- 当前仓库已经出现实现、测试和文档漂移并存的情况，需要将问题集中整理，避免后续开发继续分散推进
- 将技术债与后续方向显式化后，更有利于安排修复顺序、拆分任务和控制发布风险

## [refactor][fix][test] 将 WsReverseService 的单连接内核改为状态机并补齐生命周期测试

### 变更内容
- 将 `WsReverseService` 的连接收发逻辑从 `send_processor + read_processor + tokio::select!` 改为单任务 `ReverseWsTransfer` 状态机，统一处理发送、接收、flush 和关闭路径
- 在 reverse websocket 握手阶段引入原子连接槽位抢占，避免并发握手绕过“同一时刻只允许一个连接”的限制
- 为连接任务增加清理 guard，使连接正常关闭、异常断开、API 通道关闭、任务 abort 后都能释放 `connected` 并回收连接句柄
- 新增 reverse websocket 集成测试，覆盖二次连接拒绝、断开后重连、停止后重启、非法文本后断开清理、API 通道关闭触发本地主动关闭

### 涉及文件
- `src/communication/ws_reverse.rs` [Changed] 保留服务壳层职责，引入连接槽位原子抢占、失败升级回收和基于状态机的连接任务启动逻辑
- `src/communication/ws_reverse/transfer.rs` [Added] 新增 reverse websocket 单连接状态机，实现 API 请求发送、事件接收与关闭状态流转
- `tests/ws_reverse.rs` [Added] 新增 feature-gated 集成测试，验证 reverse websocket 生命周期与连接回收行为
- `changelogs/2026-06-01.md` [Changed] 追加本次 reverse websocket 状态机化与测试补充记录

### 影响
- `WsReverseService` 的连接生命周期与 `WsService` 更接近，连接断开后能够稳定释放占用状态，避免首个连接断开后后续重连被错误拒绝
- 并发握手场景下只会放行一个 reverse websocket 连接，减少竞态导致的状态错乱
- 不修改公开 API，仅提升 reverse websocket 的内部一致性和可验证性

### 原因
- 当前 reverse websocket 的连接状态与任务生命周期是分离的，导致 `connected` 回收不稳定，并存在握手阶段竞态
- 将单连接内核收敛为状态机后，更容易统一收发与关闭语义，也为后续整理服务运行状态问题打下基础

## [refactor][docs] 收敛 Selector 通用过滤逻辑并同步宏文档

### 变更内容
- 将 `Selector` 的通用 `filter`、`and_filter` 及其 async 版本统一下沉到 `src/selector.rs`，避免派生宏为结构体和枚举重复生成相同实现
- 将 `selector()`、枚举 `match_xxx()` 以及 `variants(...)` 生成的快捷判定方法改为 `const fn`，使只读匹配和静态上下文用法更一致
- 同步更新 selector 宏文档，说明通用过滤能力由基础 `Selector` 提供，并修正生成方法签名示例

### 涉及文件
- `src/selector.rs` [Changed] 新增 `Selector<'a, T>` 的通用同步与异步过滤方法，并将 `select`、`is_matched` 设为 `const fn`
- `macros/src/selector.rs` [Changed] 移除重复生成的通用过滤方法，将 `selector`、`match_xxx` 和变体快捷判定方法改为 `const fn`
- `macros/docs/selector.md` [Changed] 更新 selector 派生宏文档，反映基础 `Selector` 统一承载通用过滤能力后的接口形态
- `changelogs/2026-06-01.md` [Changed] 追加本次 selector 重构与文档同步记录

### 影响
- `selector` feature 下的结构体与枚举选择器继续保持原有链式过滤能力，但底层实现更集中，后续维护和扩展成本更低
- 依赖 `selector()`、`match_xxx()` 或 `variants(...)` 快捷方法的调用方无需迁移，只会获得更强的 `const` 上下文可用性

### 原因
- 通用过滤逻辑此前在宏展开结果中重复出现，既增加生成代码体积，也容易导致结构体与枚举 selector 行为漂移
- 将这部分能力收拢到基础 `Selector` 后，可以让宏更专注于生成类型专属接口，同时保持文档与实现一致

## [fix][refactor] 统一通信服务运行状态与退出语义

### 变更内容
- 为 `CommunicationService` 增加统一的 `is_running` / `take_runtime_error` 查询接口，并在 `Client` 上补充对应转发方法
- 抽出复用型服务任务状态容器，统一处理后台任务的运行标记回收、最近一次运行期错误记录与启动前错误清理
- 将 `http`、`sse`、`ws`、`ws_reverse`、`http_post` 的主后台任务改为使用统一运行态包装，避免任务异常退出后残留 `is_running = true`
- 调整 `SplitCombiner` 与 `BothEventCombiner` 的运行状态聚合语义，使组合服务能够透出子服务与内部 processor 的运行状态和最近错误
- 同步修正通信层相关 doctest 示例，使 `cargo test` 下的文档示例与当前 API 签名和 async 用法保持一致

### 涉及文件
- `src/communication/utils.rs` [Changed] 新增服务运行态容器、`CommunicationService` 默认运行态接口和 `Client` 的服务状态转发方法
- `src/communication/http.rs` [Changed] 将 HTTP 服务后台任务接入统一运行态容器，异常退出后回收运行标记并记录运行期错误
- `src/communication/sse.rs` [Changed] 将 SSE 服务监听任务接入统一运行态容器，保留事件流结束错误并允许异常退出后重启
- `src/communication/ws.rs` [Changed] 将正向 WebSocket 服务切换到统一运行态模型，保持现有重连语义同时统一状态回收
- `src/communication/ws_reverse.rs` [Changed] 为 reverse websocket 监听任务与连接任务补充统一运行态与运行期错误记录逻辑
- `src/communication/http_post.rs` [Changed] 为 HTTP Post 服务监听任务接入统一运行态容器并保留监听期错误
- `src/communication/combiner.rs` [Changed] 为 `SplitCombiner` 增加自身 processor 的运行态管理与启动失败回滚逻辑，并为两个 combiner 暴露聚合状态查询
- `src/error.rs` [Changed] 为服务运行期错误补充通用 IO 错误变体，支撑监听任务异常退出的错误透出
- `tests/ws_reverse.rs` [Changed] 补充 reverse websocket 的运行态与运行期错误观测测试
- `changelogs/2026-06-01.md` [Changed] 追加本次通信服务生命周期统一修复记录

### 影响
- 调用方现在可以通过 `Client` 或具体服务实例判断后台任务是否仍存活，并主动读取最近一次运行期错误用于排障
- `http`、`sse`、`ws_reverse`、`http_post`、`SplitCombiner` 在异常退出后不再卡在伪运行态，服务可以更可靠地再次启动
- 文档示例重新通过编译检查，降低示例代码继续漂移带来的误导风险

### 原因
- 多个通信服务此前在后台任务异常退出后没有统一回收运行状态，导致重启、诊断和组合服务行为都不稳定
- 需要给调用方一个一致的运行状态观测面，并把通信层已有的任务生命周期约束收敛到同一套内部实现

## [fix] 清理 HTTP Post 与 Reverse WebSocket 入口的 panic 路径

### 变更内容
- 去除 `HttpPostService` 请求处理器中对 `X-Signature` 和 JSON body 的输入相关 `unwrap`，改为按缺失认证、非法 header、签名错误和非法 JSON 返回明确状态码
- 收紧 `WsReverseService` 握手鉴权流程，避免对 `Authorization` 与 access token 的脆弱 `unwrap`，并为非法 header / 缺失 header / token 不匹配返回明确状态码
- 为 reverse websocket 连接任务补充错误记录，使升级成功后的连接期异常不再被静默吞掉
- 新增 HTTP Post 与 reverse websocket 集成测试，覆盖非法 header、非法 JSON、错误认证和连接错误可观测性

### 涉及文件
- `src/communication/http_post.rs` [Changed] 将 HTTP Post 入口的 header 与 JSON 解析失败改为显式状态码返回，避免外部输入触发 panic
- `src/communication/ws_reverse.rs` [Changed] 将 reverse websocket 握手认证路径改为显式分支处理，并记录连接期运行错误
- `tests/http_post.rs` [Added] 新增 HTTP Post 集成测试，验证非法签名、非法 JSON、非法 header 与合法请求的状态码行为
- `tests/ws_reverse.rs` [Changed] 新增 reverse websocket 鉴权与连接错误测试，验证异常请求不会导致服务 panic
- `changelogs/2026-06-01.md` [Changed] 追加本次协议入口 panic 路径清理记录

### 影响
- `http_post` 和 `ws_reverse` 面对非法请求时会返回稳定的 `400` / `401` / `403` / `204` 状态码，而不是让服务 panic 或静默异常
- reverse websocket 在连接异常结束后仍可继续接受后续连接，同时调用方可以通过运行期错误接口观察到最近一次连接失败原因

### 原因
- 当前协议入口仍存在由外部 header、body 或异常连接直接触发的 panic 路径，不符合库级通信组件的稳定性要求
- 需要把输入校验失败和连接期异常明确区分为“状态码反馈”与“运行期错误反馈”，提升可诊断性并消除崩溃风险
