# P6:保留清单与归档前置核对 日期:2026-09-19。本批先交付只读盘点,避免在保留周期、备份恢复和外部效果尚未评审时提供危险的自动删除入口。 ## 已实现 - [`ReadRetentionInventory`](../../internal/storage/mysql/retention_inventory.go) 接受明确的 UTC 截止时间,只统计严格早于截止时间的记录。 - `orbit-admin retention inventory --before RFC3339` 通过独立管理命令输出 JSON;数据库时间校验会拒绝未来截止时间,数据库连接、查询失败不会泄露 DSN 或 SQL。 - 盘点固定覆盖幂等、确定终态/未知效果/未终结任务、确定终态/未终结流程、已确认/未确认交付、已消费/未消费流程 Inbox、追加事件和管理审计。 - 任何查询只读,不执行 DDL、删除、搬迁、权限修改或幂等重置;CLI 没有 `apply` 参数。未确认交付、未消费 Inbox、未知效果和未终结实体被单独列为阻塞数量。 ## 回归证据 - `go test ./cmd/orbit-admin ./internal/storage/mysql` 通过;存储集成用例使用真实 MySQL 验证:明确放到截止时间之前的确定终态任务计入 `terminal_tasks`,未知效果为零,未来截止被拒绝。 - 标准 `DOCKER=... GO=... sh scripts/test-mysql.sh` 在 Go 1.27.1、Docker MySQL 8.4.10 环境退出码为 0。脚本实际输出: ```text {"cutoff":"2000-01-01T00:00:00Z","expired_idempotency":0,"terminal_tasks":0,"uncertain_tasks":0,"active_tasks":0,"terminal_workflows":0,"active_workflows":0,"acknowledged_deliveries":0,"unconfirmed_deliveries":0,"processed_inbox":0,"unprocessed_inbox":0,"events":0,"audit_events":0} ``` 同轮已有迁移、零外键、凭据、Pulse/Weave 真实进程强杀恢复、SDK 和两个独立业务示例均通过。 ## 边界与后续 盘点数量不是归档授权,也不证明某类记录可独立删除。正式归档前仍需确定每类保留周期和归档格式,核对事件交付、流程推进、有效幂等身份、未知外部效果、审计保留与备份恢复;还需要隔离环境恢复演练、权限隔离、容量和生产拓扑验证。当前没有自动清理路径,防止把测试环境的历史数量误当成生产策略。