# 原生接收崩溃残留保留期

## 实现范围

该设置只管理**已经登记、当前没有写入锁、因进程崩溃或清理失败留下的原生接收残留**。它不增加原生断点续传，不修改 LocalSend v2 的接口和报文，也不保留正常取消后的文件：现有事务析构仍即时删除其拥有的临时文件。面对原版发送设备，重新传送仍然是整文件重试。

工作区网页上传暂存和 Android SAF 清理继续使用各自的生命周期。该设置不扫描 Downloads 中所有 `.ls` 文件，不删除最终目标文件或未登记文件。登记的原生 `.ls` 缓存和原生导出 `.part` 暂存文件，都必须通过原有归属检查后才参与清理。

## 稳定的原生桥接口

所有方法均为异步方法，阻塞式登记维护在 Rust 工作线程执行。已有方法签名保持不变。

| Dart 方法 | 返回值与含义 |
| --- | --- |
| `configureReceiveCacheRetentionPolicy(mode: ..., days: ...)` | 返回策略 JSON，先校验再替换当前进程的生效策略。 |
| `getReceiveCacheRetentionPolicy()` | 返回实际生效的策略 JSON，不读取或修改缓存内容。 |
| `cleanupReceiveCacheRegistry(limit: ...)` | 原清理入口，遵循当前保留策略。 |
| `inspectReceiveCacheRegistry(limit: ...)` | 原只读检查入口，遵循当前保留策略。 |
| `cleanupReceiveCacheRegistryNow(limit: ...)` | 明确的本地用户清理，仅绕过保留年龄。 |
| `inspectReceiveCacheRegistryNow(limit: ...)` | 明确清理前的只读预览，仅绕过保留年龄。 |

策略 JSON 固定包含 `mode` 和 `days`：

```json
{"mode":"immediate","days":null}
```

```json
{"mode":"days","days":7}
```

```json
{"mode":"manual","days":null}
```

`days` 模式接受 1～3650 天，另两种模式要求天数为空。未知模式、零天、超范围天数或其他模式附带天数，都在替换前报错并保持原策略。应用负责持久化，并在自动清理开始前同步原生策略；可以先设置策略再初始化登记目录。进程默认仍为立即清理，保持既有行为。

配置写入会等待正在运行的维护批次释放策略读锁。因此配置成功返回后，不会有仍按旧策略继续删除文件的旧批次。维护批次仍有原有条目数和时间限制。本地明确清理不会修改保存的策略。启动维护及通用 API 缓存清理继续调用遵循保留期的旧入口，不会隐式绕过保留期。

## 登记时间与旧数据兼容

私有登记记录新增可选的 `registered_unix_ms`，在接收端登记时读取系统时间并写入。清理使用这份持久时间，不使用远端文件时间、缓存身份时间、登记文件修改时间或启动时间。重新打开登记目录不会重置年龄。一天按 86400 秒计算，到达设定边界时才进入可清理状态。

旧记录没有时间字段时仍可读取并通过校验和检查：缺失的可选字段在序列化时继续省略。按天清理会保留这类记录，不猜测年龄。立即清理和明确的本地清理继续遵循原来的资格检查。系统时间不可用或早于登记时间时也保留文件。这是进程崩溃残留登记，不增加断电持久化保证，也不是可续传任务清单。

## 安全检查优先级与报告原因

先执行原有检查：登记记录、来源及校验和有效；登记文件没有活动锁；父目录与文件身份匹配；目标为普通文件；缓存没有活动锁；缓存头身份有效。保留期不会掩盖活动状态或身份异常。父目录身份有效且登记的临时文件已经消失时，所有策略下仍可清退过期登记；父目录不可访问时继续保护。

报告字段、匿名标识和处置类型保持不变。公开报告不增加本地路径、设备身份、会话凭据或登记时间。因为保留期而留下的条目，其计划删除字节数为零。新增稳定原因码如下：

| 原因码 | 含义 |
| --- | --- |
| `retention_period` | 已核验的原生残留尚未达到保留天数。 |
| `retention_manual` | 已核验的原生残留等待明确的本地清理。 |
| `retention_age_unknown` | 按天模式遇到旧记录或登记时时钟不可用，没有可靠登记时间。 |
| `retention_clock_unverified` | 当前时间不可用或早于登记时间。 |

## 验证记录

- 登记单元测试 23 项通过，其中新增 7 项覆盖注入时钟、真实登记与重新打开、旧校验和兼容、年龄精确边界、时钟回拨、配置失败原子性、活动锁、文件身份变化、无效缓存头和已消失文件登记。
- 原有原生 HTTP 缓存测试 4 项通过，覆盖整文件重试与校验和、取消、停滞请求体、断连及服务器停止，原行为保持。
- 进程场景测试 2 项通过：真实 HTTP 子进程写入登记缓存，普通清理和明确清理均跳过活动锁；强制结束子进程后，手动保留及一天保留均保留残留；明确清理只删除已登记残留，不碰用户 `.ls` 文件和已发布文件。
- 新构建的真实原生桥测试 1 项通过：实际策略读取、无效配置后原策略不变、活动任务期间两个明确清理入口的保护、手动保留下正常取消仍即时清理，以及下一次原生传输成功。
- 额外执行全核心严格 Clippy（`-- -D warnings`）时，未改动的加密、HTTP 客户端/服务端和 WebRTC 文件报告 32 项既有诊断，保留期模块没有诊断；不将全核心严格 lint 标记为通过。

以上为核心逻辑及 macOS 宿主验证，不代替 Android/iOS 实体设备验收，也不表示实现原生部分续传。
