zizi 0260bcd8e2 设计文档:SoT 同步与生成物重出
- 新版设计各域 SoT 按本轮实现同步:总体架构、模块设计、接口契约、数据模型、功能规格、文件设计与决策记录。
- 接口契约生成物重新导出(openapi 与前端客户端随契约一致)。
- 实现回顾与专项检查台账保留历史结论;本轮收尾发现另见 .agents.local 下的收尾报告与审查处置。
2026-09-18 01:15:18 +08:00

80 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- 导航元信息: {"内容描述": "原文证据生命周期", "使用场景": "设计、重写或迁移核对", "使用要求": "以本主题合同为准"} -->
# 原文、证据与归档生命周期
本文是 S02 原文授权、保留和恢复的目标合同。它承接旧 raw vault 的有效保护,并将持久状态收进 PostgreSQL;临时文件的物理布局不成为新版必须复刻的接口。
## 内容分类
| 类别 | 内容与权威 | 允许的保存与消费 |
|------|------------|----------------|
| 临时敏感原文 | 仅获本次评测或处理授权的完整输入、输出字节;租约登记在 PG,字节在受控暂存 | 有效期限内按明确任务与用途使用;不得自动写入普通运行证据、日志、测试夹具或文稿导出 |
| 持久运行证据 | 获准保存的输入、响应、来源版本、模型与调用记录;S02 的 PG 记录 | 按证据权限读取;只有哈希时明确标为只有哈希,不能声称保有完整可回放原文 |
| 受控归档 | 作者明确批准长期保存的原文字节与完整清单;归档内容、身份与回执进入 PG | 独立归档授权;退出临时租约不等于允许删除归档,普通暂存清理无权清理此类内容 |
24 小时限制针对临时敏感原文,不删除作者正式正文、已授权研究原文或合法持久证据。旧受控文件归档先作为迁移来源读取,完整入库并核对后才按其保留授权处置旧载体。
## 授权与租约
创建请求含 authorization_id、task_id、run_purpose、source_version、content_hashes、purpose、retain_until、min_remaining;选择归档时另含 archive_authorization_id 与目标归档范围。approved_by 从已验证的作者决定取得,不能仅凭调用方填写“用户”或“创始人”字符串通过。
授权必须覆盖具体来源、内容哈希、用途与保存方式。任务用途不能通过内容用途提升权限;评测素材的授权也不能转成生产采纳权限。哈希集合非空、格式合法,时间必须带时区。
尚未生成的模型响应按具体调用授权:批准记录同时固定 `call_id` 与完整模型请求的 `call_request_hash`,输入哈希集合包含该请求哈希。S02 在发送前核对绑定,在该调用已经登记发出后记录唯一的 `response_hash`;重复登记只接受相同哈希。响应绑定是调用事实,不修改原批准范围,不覆盖另一轮工具调用或重试。未批准响应保留的请求不能在返回后自动扩充授权。临时响应仍受原租约期限约束;持久保存和归档分别使用原有保存方式合同。
临时租约满足 `0 < retain_until - created_at <= 24h`。剩余时间至少覆盖下一次调用的总期限及清理余量,否则在创建原文、占用调用预算或启动模型之前拒绝。每次写入和普通读取重新核对授权、租约与截止时间;过期后禁止继续消费,清理与恢复仍可执行。
单次模型调用可以显式提供临时租约。发送前核对租约与本次批准一致,输入先写入租约;响应绑定确切调用后保存到同一租约。普通PG运行证据只记录哈希、结果状态和raw_lease_id,不自动复制全文。调用确认保存时实际回读租约字节;暂存失败另记失败证据,已发生费用保留。证据回执的hash_only描述普通PG记录,不代表租约当前仍持有完整原文;临时可用性以原文服务实读和状态为准。
清理租约不改写已发生的调用结果。需要完整长期证据时,取得明确持久保留批准后按同哈希补交;归档使用独立归档批准。单次模型返回不代替整个评测流程的归档接受条件。
### 角色会话的派生回合
多轮工具探索使用明确的会话保留授权,不能复用单次调用批准来扩大范围。会话批准固定 `role_session_id`、初始角色请求哈希、后端来源范围哈希、角色与构建、允许工具、模型/工具次数上限、保存方式和总截止时间;作者身份仍从已验证接入取得。该批准明确包含本次有限会话的派生输入、模型输出和工具结果,不改变来源读取权或正式采纳权。
S02只允许由固定初始输入、本会话已经核对的模型输出及具名工具结果构造下一回合。每次派生记录绑定当前尝试、回合身份、请求哈希、前序模型回执和工具回执,并引用父批准;它表示继承的范围,不伪造一次新的作者批准。先持久化派生授权,再记录原文、预留预算和发送。每个回合的响应继续唯一绑定其自身调用,不能覆盖上一回合。
派生不能增加来源、工具、次数、保存方式或期限。父批准被撤销、截止、来源失效或执行构建变化后不能继续派生;已有字节仍按原保留/归档合同处理。普通单次授权仍只允许原调用。当前会话入口先承接persistent保存方式,temporary会话需使用临时租约链后另行验收,不通过现有会话入口自动转成持久保存。
恢复允许引用同一任务、同一会话中原尝试已保存的模型和工具回执。重建前及每次消费时核对当前owner来源检查、父子批准与费用状态;原证据和批准不迁到新尝试名下。只有后续新回合登记新尝试,派生记录保留前序回执关联。缺失或失败的历史不能以重新外发替代补交和对账。
## 状态与转换
| 原状态 | 动作与前置条件 | 结果及失败边界 |
|--------|----------------|----------------|
| 无 | 有效授权;先持久化非敏感租约,再建立受控暂存 | open;租约未可靠保存不得出现原文字节 |
| open | 有效租约下写入 | 保持 open;身份、内容范围、越界路径或权限不符则拒绝 |
| open | 作者批准清理或临时期限结束 | 先清理字节,成功后 closed;失败保持清理待恢复,不能伪报已删除 |
| open | 归档授权有效;完整清单与字节可核对 | 先记 migrating,再导入归档;迁移过程禁止普通消费和并发写入 |
| migrating | 同一 archive_id 的全部字节、内容树哈希、条目数、总字节数、权限和回执在 PG 事务内提交 | migrated;只有元数据或只有一部分字节不能迁移成功 |
| migrating | PG 提交失败、结果未知或清理前崩溃 | 保留源或已提交归档,标为需要恢复;以 archive_id、内容哈希与回执对账,不能退回普通删除路径 |
| migrated | 核对 PG 完整归档后清理临时副本 | 保留 migrated 与清理回执;重复请求返回同一归档,不能重复建立内容 |
| closed | 发现旧命名空间残留 | 仅清理本管理器残留并补记回执;不跟随软链接、不扫其他暂存或归档 |
进入 migrating 必须已经具备覆盖归档与恢复的授权。临时期限到达后,迁移中的字节只供受控恢复,不能继续模型调用;不以延长临时租约掩盖归档失败。无归档授权的 open 原文到期执行清理,记录证据缺失和失败,不能私自改成永久保留。
任务标记成功要求其所需证据已可靠保存;要求归档的评测只有 migrated 且回执可核对才满足该条件。迁移失败不能因模型输出完整而被计作成功。清理失败和内容丢失分别记录,不能补造原文或回执。
## 路径与恢复
运行证据以“尝试、种类、调用身份”区分调用事件,内容哈希只用于字节校验和同一证据补交。不同调用返回相同文本仍保留各自证据;同一调用不能换字节或结果覆盖旧证据。没有调用身份的导入或补交记录以确切内容哈希固定身份,不用于合并模型或工具调用。
原文对象只通过不透明 ID 访问。受控文件实现使用管理器生成的路径、排他创建和不跟随软链接的逐级访问,目录权限 0700、文件权限 0600;不修改系统共享临时根的权限。正文、绝对路径和凭据不进入普通回执或错误日志。
恢复先读取租约及归档状态。open 的遗留临时原文按终止或到期合同清理;migrating 先对账并续接归档;migrated 核对后清理临时副本;closed 残留和本命名空间无租约孤儿可清理。未知或损坏记录先隔离并报告,不把整个目录当成可删对象。PG 不可用时不得臆测 migrating 状态后清理。
任务failed仍可恢复,不视为取消或完成终态;有效open租约继续保留,供重验、恢复或明确归档。任务取消或完成后的清理不改变正式文稿、持久证据及归档的保留状态。
暂存根以数据库生成的不可变命名空间身份和运行用途绑定;标记不能由调用参数改变。首次绑定只接受空目录;未标记的非空根、损坏标记或另一数据库/用途的根拒绝接管。纯PG证据和归档读取不要求本地暂存根,只有文件动作核对该绑定。
同一应用实例、同一用途的HTTP与worker使用同一个共享暂存根。迁移根须停下相关消费并整体迁移标记与对象;不能把一个根的清理完成当作任意额外物理副本也已删除。
无租约清理先枚举本根候选,再在新事务中查询已登记租约。利用“先提交租约再创建字节”的顺序,候选在被查询时已能看到对应登记,不会把刚生成对象当作孤儿。所有已登记对象(包括migrating)都保留。未知资料不删除。无租约既不证明授权也不证明可删:旧「清理无租约暂存」入口只盘点,把无租约对象列为 `needs_recovery` 交人工核对,不写清理意图、不删除文件,也不伪造清理回执。物理清理只走具名到期回收两段式:先按租约元数据与命名空间发现候选(`as_of`/游标/上限,调度默认关闭),再由作者对具名计划执行;执行段复用租约状态机与 `cleanup_receipt`,覆盖有效open、migrating、已migrated 与未知对象各自的保留理由,重试沿用同一回执,实际已不存在就如实记录,不补造删除动作。
旧状态 open、closed、migrating、migrated 与原授权、截止时间、内容哈希、归档回执原样进入迁移清单。旧 migrate 的同文件系统 rename 改为完整 PG 事务归档;保留的是“原文不丢、回执可信、恢复不误删”,不再要求重写相同 rename 调用。
## 实现与逐例验收
S02 的原文生命周期.py 拥有授权、租约和转换,运行证据.py 负责证据关联;基础设施的受控文件.py 承担文件访问,文件保留.py 只执行状态允许的清理。数据库迁移 V0004 定义租约、归档与清理回执,B10 逐例执行消费同一合同。
新用例分别覆盖:授权伪造;超过 24 小时;不足一次调用余量;先租约后字节;过期拒写但可清理;路径越界与软链接;清理失败不关闭;迁移中断不删源;归档事务回滚;提交结果未知后的幂等恢复;缺完整字节不能成功;旧归档导入;日志与回执无原文路径。纯规则使用假时钟与临时目录,归档事务及恢复使用隔离 PG。测试身份见[现行用例清单](../../../../tests/用例清单.json),隔离与证据原则见[测试隔离规则](../../../../.agent/rules/测试隔离.md)。